Sidebar: show "last active subs" instead of "by name"
1003
This commit is contained in:
parent
4a5e967628
commit
b5bd36839e
11 changed files with 186 additions and 45 deletions
1
flow-typed/subscription.js
vendored
1
flow-typed/subscription.js
vendored
|
@ -13,6 +13,7 @@ declare type Following = {
|
||||||
|
|
||||||
declare type SubscriptionState = {
|
declare type SubscriptionState = {
|
||||||
subscriptions: Array<Subscription>,
|
subscriptions: Array<Subscription>,
|
||||||
|
lastActiveSubscriptions: ?Array<Subscription>,
|
||||||
following: Array<Following>,
|
following: Array<Following>,
|
||||||
loading: boolean,
|
loading: boolean,
|
||||||
firstRunCompleted: boolean,
|
firstRunCompleted: boolean,
|
||||||
|
|
|
@ -2217,5 +2217,7 @@
|
||||||
"Only Language": "Only Language",
|
"Only Language": "Only Language",
|
||||||
"Only Homepage": "Only Homepage",
|
"Only Homepage": "Only Homepage",
|
||||||
"Choose Your Preference": "Choose Your Preference",
|
"Choose Your Preference": "Choose Your Preference",
|
||||||
|
"Recently Active": "Recently Active",
|
||||||
|
"All Channels": "All Channels",
|
||||||
"--end--": "--end--"
|
"--end--": "--end--"
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
|
import { doFetchLastActiveSubs } from 'redux/actions/subscriptions';
|
||||||
import { selectActiveChannelStakedLevel } from 'redux/selectors/app';
|
import { selectActiveChannelStakedLevel } from 'redux/selectors/app';
|
||||||
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
import { selectLastActiveSubscriptions, selectSubscriptions } from 'redux/selectors/subscriptions';
|
||||||
import { doClearClaimSearch } from 'redux/actions/claims';
|
import { doClearClaimSearch } from 'redux/actions/claims';
|
||||||
import { doClearPurchasedUriSuccess } from 'redux/actions/file';
|
import { doClearPurchasedUriSuccess } from 'redux/actions/file';
|
||||||
import { selectFollowedTags } from 'redux/selectors/tags';
|
import { selectFollowedTags } from 'redux/selectors/tags';
|
||||||
|
@ -14,6 +15,7 @@ import SideNavigation from './view';
|
||||||
|
|
||||||
const select = (state) => ({
|
const select = (state) => ({
|
||||||
subscriptions: selectSubscriptions(state),
|
subscriptions: selectSubscriptions(state),
|
||||||
|
lastActiveSubs: selectLastActiveSubscriptions(state),
|
||||||
followedTags: selectFollowedTags(state),
|
followedTags: selectFollowedTags(state),
|
||||||
email: selectUserVerifiedEmail(state),
|
email: selectUserVerifiedEmail(state),
|
||||||
purchaseSuccess: selectPurchaseUriSuccess(state),
|
purchaseSuccess: selectPurchaseUriSuccess(state),
|
||||||
|
@ -28,4 +30,5 @@ export default connect(select, {
|
||||||
doClearClaimSearch,
|
doClearClaimSearch,
|
||||||
doSignOut,
|
doSignOut,
|
||||||
doClearPurchasedUriSuccess,
|
doClearPurchasedUriSuccess,
|
||||||
|
doFetchLastActiveSubs,
|
||||||
})(SideNavigation);
|
})(SideNavigation);
|
||||||
|
|
|
@ -104,6 +104,7 @@ const WILD_WEST = {
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
subscriptions: Array<Subscription>,
|
subscriptions: Array<Subscription>,
|
||||||
|
lastActiveSubs: ?Array<Subscription>,
|
||||||
followedTags: Array<Tag>,
|
followedTags: Array<Tag>,
|
||||||
email: ?string,
|
email: ?string,
|
||||||
uploadCount: number,
|
uploadCount: number,
|
||||||
|
@ -120,11 +121,13 @@ type Props = {
|
||||||
activeChannelStakedLevel: number,
|
activeChannelStakedLevel: number,
|
||||||
wildWestDisabled: boolean,
|
wildWestDisabled: boolean,
|
||||||
doClearClaimSearch: () => void,
|
doClearClaimSearch: () => void,
|
||||||
|
doFetchLastActiveSubs: (count?: number) => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
function SideNavigation(props: Props) {
|
function SideNavigation(props: Props) {
|
||||||
const {
|
const {
|
||||||
subscriptions,
|
subscriptions,
|
||||||
|
lastActiveSubs,
|
||||||
doSignOut,
|
doSignOut,
|
||||||
email,
|
email,
|
||||||
purchaseSuccess,
|
purchaseSuccess,
|
||||||
|
@ -140,6 +143,7 @@ function SideNavigation(props: Props) {
|
||||||
activeChannelStakedLevel,
|
activeChannelStakedLevel,
|
||||||
wildWestDisabled,
|
wildWestDisabled,
|
||||||
doClearClaimSearch,
|
doClearClaimSearch,
|
||||||
|
doFetchLastActiveSubs,
|
||||||
} = props;
|
} = props;
|
||||||
|
|
||||||
const isLargeScreen = useIsLargeScreen();
|
const isLargeScreen = useIsLargeScreen();
|
||||||
|
@ -309,11 +313,10 @@ function SideNavigation(props: Props) {
|
||||||
const filter = subscriptionFilter.toLowerCase();
|
const filter = subscriptionFilter.toLowerCase();
|
||||||
displayedSubscriptions = subscriptions.filter((sub) => sub.channelName.toLowerCase().includes(filter));
|
displayedSubscriptions = subscriptions.filter((sub) => sub.channelName.toLowerCase().includes(filter));
|
||||||
} else {
|
} else {
|
||||||
displayedSubscriptions = subscriptions.slice(0, SIDEBAR_SUBS_DISPLAYED);
|
displayedSubscriptions = lastActiveSubs || subscriptions.slice(0, SIDEBAR_SUBS_DISPLAYED);
|
||||||
}
|
}
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<>
|
|
||||||
<ul className="navigation__secondary navigation-links">
|
<ul className="navigation__secondary navigation-links">
|
||||||
{subscriptions.length > SIDEBAR_SUBS_DISPLAYED && (
|
{subscriptions.length > SIDEBAR_SUBS_DISPLAYED && (
|
||||||
<li className="navigation-item">
|
<li className="navigation-item">
|
||||||
|
@ -339,7 +342,6 @@ function SideNavigation(props: Props) {
|
||||||
/>
|
/>
|
||||||
)}
|
)}
|
||||||
</ul>
|
</ul>
|
||||||
</>
|
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -418,6 +420,10 @@ function SideNavigation(props: Props) {
|
||||||
}
|
}
|
||||||
}, [sidebarOpen]);
|
}, [sidebarOpen]);
|
||||||
|
|
||||||
|
React.useEffect(() => {
|
||||||
|
doFetchLastActiveSubs();
|
||||||
|
}, []);
|
||||||
|
|
||||||
const unAuthNudge =
|
const unAuthNudge =
|
||||||
DOMAIN === 'lbry.tv' ? null : (
|
DOMAIN === 'lbry.tv' ? null : (
|
||||||
<div className="navigation__auth-nudge">
|
<div className="navigation__auth-nudge">
|
||||||
|
|
|
@ -324,6 +324,9 @@ export const CHECK_SUBSCRIPTIONS_SUBSCRIBE = 'CHECK_SUBSCRIPTIONS_SUBSCRIBE';
|
||||||
export const FETCH_SUBSCRIPTIONS_START = 'FETCH_SUBSCRIPTIONS_START';
|
export const FETCH_SUBSCRIPTIONS_START = 'FETCH_SUBSCRIPTIONS_START';
|
||||||
export const FETCH_SUBSCRIPTIONS_FAIL = 'FETCH_SUBSCRIPTIONS_FAIL';
|
export const FETCH_SUBSCRIPTIONS_FAIL = 'FETCH_SUBSCRIPTIONS_FAIL';
|
||||||
export const FETCH_SUBSCRIPTIONS_SUCCESS = 'FETCH_SUBSCRIPTIONS_SUCCESS';
|
export const FETCH_SUBSCRIPTIONS_SUCCESS = 'FETCH_SUBSCRIPTIONS_SUCCESS';
|
||||||
|
export const FETCH_LAST_ACTIVE_SUBS_SKIP = 'FETCH_LAST_ACTIVE_SUBS_SKIP';
|
||||||
|
export const FETCH_LAST_ACTIVE_SUBS_DONE = 'FETCH_LAST_ACTIVE_SUBS_DONE';
|
||||||
|
export const FETCH_LAST_ACTIVE_SUBS_FAIL = 'FETCH_LAST_ACTIVE_SUBS_FAIL';
|
||||||
export const SET_VIEW_MODE = 'SET_VIEW_MODE';
|
export const SET_VIEW_MODE = 'SET_VIEW_MODE';
|
||||||
|
|
||||||
// Publishing
|
// Publishing
|
||||||
|
|
|
@ -1,10 +1,11 @@
|
||||||
import { connect } from 'react-redux';
|
import { connect } from 'react-redux';
|
||||||
import { doResolveUris } from 'redux/actions/claims';
|
import { doResolveUris } from 'redux/actions/claims';
|
||||||
import { selectSubscriptionUris } from 'redux/selectors/subscriptions';
|
import { selectLastActiveSubscriptions, selectSubscriptionUris } from 'redux/selectors/subscriptions';
|
||||||
import ChannelsFollowingManage from './view';
|
import ChannelsFollowingManage from './view';
|
||||||
|
|
||||||
const select = (state) => ({
|
const select = (state) => ({
|
||||||
subscribedChannelUris: selectSubscriptionUris(state),
|
subscribedChannelUris: selectSubscriptionUris(state),
|
||||||
|
lastActiveSubs: selectLastActiveSubscriptions(state),
|
||||||
});
|
});
|
||||||
|
|
||||||
const perform = {
|
const perform = {
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
// @flow
|
// @flow
|
||||||
import React from 'react';
|
import React from 'react';
|
||||||
|
import Button from 'component/button';
|
||||||
|
import ChannelThumbnail from 'component/channelThumbnail';
|
||||||
import ClaimList from 'component/claimList';
|
import ClaimList from 'component/claimList';
|
||||||
|
import ClaimPreviewTitle from 'component/claimPreviewTitle';
|
||||||
import DebouncedInput from 'component/common/debounced-input';
|
import DebouncedInput from 'component/common/debounced-input';
|
||||||
import Empty from 'component/common/empty';
|
import Empty from 'component/common/empty';
|
||||||
import Page from 'component/page';
|
import Page from 'component/page';
|
||||||
import Spinner from 'component/spinner';
|
import Spinner from 'component/spinner';
|
||||||
import * as ICONS from 'constants/icons';
|
import * as ICONS from 'constants/icons';
|
||||||
|
import { SIDEBAR_SUBS_DISPLAYED } from 'constants/subscriptions';
|
||||||
|
|
||||||
function getFilteredUris(uris, filterQuery) {
|
function getFilteredUris(uris, filterQuery) {
|
||||||
if (filterQuery) {
|
if (filterQuery) {
|
||||||
|
@ -23,11 +27,12 @@ const FOLLOW_PAGE_SIZE = 30;
|
||||||
|
|
||||||
type Props = {
|
type Props = {
|
||||||
subscribedChannelUris: Array<string>,
|
subscribedChannelUris: Array<string>,
|
||||||
|
lastActiveSubs: ?Array<Subscription>,
|
||||||
doResolveUris: (uris: Array<string>, returnCachedClaims: boolean, resolveReposts: boolean) => void,
|
doResolveUris: (uris: Array<string>, returnCachedClaims: boolean, resolveReposts: boolean) => void,
|
||||||
};
|
};
|
||||||
|
|
||||||
export default function ChannelsFollowingManage(props: Props) {
|
export default function ChannelsFollowingManage(props: Props) {
|
||||||
const { subscribedChannelUris, doResolveUris } = props;
|
const { subscribedChannelUris, lastActiveSubs, doResolveUris } = props;
|
||||||
|
|
||||||
// The locked-on-mount full set of subscribed uris.
|
// The locked-on-mount full set of subscribed uris.
|
||||||
const [uris, setUris] = React.useState([]);
|
const [uris, setUris] = React.useState([]);
|
||||||
|
@ -95,7 +100,40 @@ export default function ChannelsFollowingManage(props: Props) {
|
||||||
|
|
||||||
{filteredUris && <ClaimList uris={filteredUris} />}
|
{filteredUris && <ClaimList uris={filteredUris} />}
|
||||||
|
|
||||||
|
{!filteredUris && lastActiveSubs && lastActiveSubs.length === SIDEBAR_SUBS_DISPLAYED && (
|
||||||
|
<>
|
||||||
|
<div className="card__title-section">
|
||||||
|
<div className="card__subtitle"> {__('Recently Active')}</div>
|
||||||
|
</div>
|
||||||
|
<div className="followManage-wrapper__activeSubs">
|
||||||
|
{lastActiveSubs.map((sub) => {
|
||||||
|
return (
|
||||||
|
<div key={sub.uri} className="navigation-link__wrapper navigation__subscription">
|
||||||
|
<Button
|
||||||
|
navigate={sub.uri}
|
||||||
|
className="navigation-link navigation-link--with-thumbnail"
|
||||||
|
activeClass="navigation-link--active"
|
||||||
|
>
|
||||||
|
<ChannelThumbnail xsmall uri={sub.uri} hideStakedIndicator />
|
||||||
|
<div className="navigation__subscription-title">
|
||||||
|
<ClaimPreviewTitle uri={sub.uri} />
|
||||||
|
<span dir="auto" className="channel-name">
|
||||||
|
{sub.channelName}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</Button>
|
||||||
|
</div>
|
||||||
|
);
|
||||||
|
})}
|
||||||
|
</div>
|
||||||
|
</>
|
||||||
|
)}
|
||||||
|
|
||||||
{!filteredUris && uris.length > 0 && (
|
{!filteredUris && uris.length > 0 && (
|
||||||
|
<>
|
||||||
|
<div className="card__title-section">
|
||||||
|
<div className="card__subtitle"> {__('All Channels')}</div>
|
||||||
|
</div>
|
||||||
<ClaimList
|
<ClaimList
|
||||||
uris={uris.slice(0, (page + 1) * FOLLOW_PAGE_SIZE)}
|
uris={uris.slice(0, (page + 1) * FOLLOW_PAGE_SIZE)}
|
||||||
onScrollBottom={bumpPage}
|
onScrollBottom={bumpPage}
|
||||||
|
@ -104,6 +142,7 @@ export default function ChannelsFollowingManage(props: Props) {
|
||||||
loading={loadingPage}
|
loading={loadingPage}
|
||||||
useLoadingSpinner
|
useLoadingSpinner
|
||||||
/>
|
/>
|
||||||
|
</>
|
||||||
)}
|
)}
|
||||||
</>
|
</>
|
||||||
)}
|
)}
|
||||||
|
|
|
@ -1,11 +1,15 @@
|
||||||
// @flow
|
// @flow
|
||||||
|
import Lbry from 'lbry';
|
||||||
import * as ACTIONS from 'constants/action_types';
|
import * as ACTIONS from 'constants/action_types';
|
||||||
|
import { SIDEBAR_SUBS_DISPLAYED } from 'constants/subscriptions';
|
||||||
import REWARDS from 'rewards';
|
import REWARDS from 'rewards';
|
||||||
import { Lbryio } from 'lbryinc';
|
import { Lbryio } from 'lbryinc';
|
||||||
import { doClaimRewardType } from 'redux/actions/rewards';
|
import { doClaimRewardType } from 'redux/actions/rewards';
|
||||||
|
import { getChannelFromClaim } from 'util/claim';
|
||||||
import { parseURI } from 'util/lbryURI';
|
import { parseURI } from 'util/lbryURI';
|
||||||
import { doAlertWaitingForSync } from 'redux/actions/app';
|
import { doAlertWaitingForSync } from 'redux/actions/app';
|
||||||
import { doToast } from 'redux/actions/notifications';
|
import { doToast } from 'redux/actions/notifications';
|
||||||
|
import { selectSubscriptions } from 'redux/selectors/subscriptions';
|
||||||
|
|
||||||
type SubscriptionArgs = {
|
type SubscriptionArgs = {
|
||||||
channelName: string,
|
channelName: string,
|
||||||
|
@ -13,6 +17,9 @@ type SubscriptionArgs = {
|
||||||
notificationsDisabled?: boolean,
|
notificationsDisabled?: boolean,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const FETCH_LAST_ACTIVE_SUBS_MIN_INTERVAL_MS = 5 * 60 * 1000;
|
||||||
|
let activeSubsLastFetchedTime = 0;
|
||||||
|
|
||||||
export function doToggleSubscription(
|
export function doToggleSubscription(
|
||||||
subscription: SubscriptionArgs,
|
subscription: SubscriptionArgs,
|
||||||
followToast: boolean,
|
followToast: boolean,
|
||||||
|
@ -71,6 +78,9 @@ export function doToggleSubscription(
|
||||||
})
|
})
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Reset last-fetch counter
|
||||||
|
activeSubsLastFetchedTime = 0;
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -85,3 +95,48 @@ export function doChannelUnsubscribe(subscription: SubscriptionArgs, followToast
|
||||||
return dispatch(doToggleSubscription(subscription, followToast, true));
|
return dispatch(doToggleSubscription(subscription, followToast, true));
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function doFetchLastActiveSubs(forceFetch: boolean = false, count: number = SIDEBAR_SUBS_DISPLAYED) {
|
||||||
|
function parseIdFromUri(uri) {
|
||||||
|
try {
|
||||||
|
const { channelClaimId } = parseURI(uri);
|
||||||
|
return channelClaimId;
|
||||||
|
} catch {
|
||||||
|
return '';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return (dispatch: Dispatch, getState: GetState) => {
|
||||||
|
const now = Date.now();
|
||||||
|
if (!forceFetch && now - activeSubsLastFetchedTime < FETCH_LAST_ACTIVE_SUBS_MIN_INTERVAL_MS) {
|
||||||
|
dispatch({ type: ACTIONS.FETCH_LAST_ACTIVE_SUBS_SKIP });
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const state = getState();
|
||||||
|
const subscriptions = selectSubscriptions(state);
|
||||||
|
const channelIds = subscriptions.map((sub) => parseIdFromUri(sub.uri));
|
||||||
|
activeSubsLastFetchedTime = now;
|
||||||
|
|
||||||
|
const searchOptions = {
|
||||||
|
limit_claims_per_channel: 1,
|
||||||
|
channel_ids: channelIds,
|
||||||
|
claim_type: ['stream', 'repost'],
|
||||||
|
page: 1,
|
||||||
|
page_size: count,
|
||||||
|
no_totals: true,
|
||||||
|
order_by: ['release_time'],
|
||||||
|
};
|
||||||
|
|
||||||
|
Lbry.claim_search(searchOptions)
|
||||||
|
.then((result) => {
|
||||||
|
dispatch({
|
||||||
|
type: ACTIONS.FETCH_LAST_ACTIVE_SUBS_DONE,
|
||||||
|
data: result.items.map((claim) => getChannelFromClaim(claim)),
|
||||||
|
});
|
||||||
|
})
|
||||||
|
.catch(() => {
|
||||||
|
dispatch({ type: ACTIONS.FETCH_LAST_ACTIVE_SUBS_FAIL });
|
||||||
|
});
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import { handleActions } from 'util/redux-utils';
|
||||||
|
|
||||||
const defaultState: SubscriptionState = {
|
const defaultState: SubscriptionState = {
|
||||||
subscriptions: [], // Deprecated
|
subscriptions: [], // Deprecated
|
||||||
|
lastActiveSubscriptions: undefined, // undefined = un-fetched, null = no results;
|
||||||
following: [],
|
following: [],
|
||||||
loading: false,
|
loading: false,
|
||||||
firstRunCompleted: false,
|
firstRunCompleted: false,
|
||||||
|
@ -49,13 +50,13 @@ export default handleActions(
|
||||||
[ACTIONS.CHANNEL_UNSUBSCRIBE]: (state: SubscriptionState, action): SubscriptionState => {
|
[ACTIONS.CHANNEL_UNSUBSCRIBE]: (state: SubscriptionState, action): SubscriptionState => {
|
||||||
const subscriptionToRemove: Subscription = action.data;
|
const subscriptionToRemove: Subscription = action.data;
|
||||||
|
|
||||||
const newSubscriptions = state.subscriptions
|
const newSubscriptions = state.subscriptions.filter(
|
||||||
.slice()
|
(subscription) => !isURIEqual(subscription.uri, subscriptionToRemove.uri)
|
||||||
.filter((subscription) => !isURIEqual(subscription.uri, subscriptionToRemove.uri));
|
);
|
||||||
|
|
||||||
const newFollowing = state.following
|
const newFollowing = state.following.filter(
|
||||||
.slice()
|
(subscription) => !isURIEqual(subscription.uri, subscriptionToRemove.uri)
|
||||||
.filter((subscription) => !isURIEqual(subscription.uri, subscriptionToRemove.uri));
|
);
|
||||||
|
|
||||||
return {
|
return {
|
||||||
...state,
|
...state,
|
||||||
|
@ -76,6 +77,25 @@ export default handleActions(
|
||||||
loading: false,
|
loading: false,
|
||||||
subscriptions: action.data,
|
subscriptions: action.data,
|
||||||
}),
|
}),
|
||||||
|
[ACTIONS.FETCH_LAST_ACTIVE_SUBS_DONE]: (state: SubscriptionState, action): SubscriptionState => {
|
||||||
|
const activeChannelClaims = action.data;
|
||||||
|
if (activeChannelClaims && activeChannelClaims.length > 0) {
|
||||||
|
const subs = [];
|
||||||
|
activeChannelClaims.forEach((claim) => {
|
||||||
|
const index = state.subscriptions.findIndex((sub) => isURIEqual(sub.uri, claim.permanent_url));
|
||||||
|
if (index !== -1) {
|
||||||
|
subs.push(state.subscriptions[index]);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
return { ...state, lastActiveSubscriptions: subs };
|
||||||
|
}
|
||||||
|
return { ...state, lastActiveSubscriptions: null };
|
||||||
|
},
|
||||||
|
[ACTIONS.FETCH_LAST_ACTIVE_SUBS_FAIL]: (state: SubscriptionState, action): SubscriptionState => ({
|
||||||
|
...state,
|
||||||
|
lastActiveSubscriptions: null,
|
||||||
|
}),
|
||||||
[ACTIONS.SET_VIEW_MODE]: (state: SubscriptionState, action): SubscriptionState => ({
|
[ACTIONS.SET_VIEW_MODE]: (state: SubscriptionState, action): SubscriptionState => ({
|
||||||
...state,
|
...state,
|
||||||
viewMode: action.data,
|
viewMode: action.data,
|
||||||
|
|
|
@ -25,6 +25,8 @@ export const selectSubscriptionUris = createSelector(
|
||||||
(subscriptions) => subscriptions && subscriptions.map((sub) => sub.uri)
|
(subscriptions) => subscriptions && subscriptions.map((sub) => sub.uri)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
export const selectLastActiveSubscriptions = (state) => selectState(state).lastActiveSubscriptions;
|
||||||
|
|
||||||
export const selectFollowing = createSelector(selectState, (state) => state.following && state.following);
|
export const selectFollowing = createSelector(selectState, (state) => state.following && state.following);
|
||||||
|
|
||||||
// Fetching list of users subscriptions
|
// Fetching list of users subscriptions
|
||||||
|
|
|
@ -664,6 +664,15 @@ img {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.followManage-wrapper__activeSubs {
|
||||||
|
-moz-column-count: 2;
|
||||||
|
-moz-column-gap: var(--spacing-m);
|
||||||
|
-webkit-column-count: 2;
|
||||||
|
-webkit-column-gap: var(--spacing-m);
|
||||||
|
column-count: 2;
|
||||||
|
column-gap: var(--spacing-m);
|
||||||
|
}
|
||||||
|
|
||||||
.uploadPage-wraper {
|
.uploadPage-wraper {
|
||||||
&.card-stack {
|
&.card-stack {
|
||||||
.card:not(:last-of-type) {
|
.card:not(:last-of-type) {
|
||||||
|
|
Loading…
Reference in a new issue