allow unsubscribe from deleted channels by navigating from sidebar

This commit is contained in:
zeppi 2021-04-28 23:44:29 -04:00 committed by jessopb
parent cba369a5ce
commit b9fc9b6319
5 changed files with 68 additions and 31 deletions

View file

@ -1886,7 +1886,6 @@
"No replays found.": "No replays found.",
"Replay video available": "Replay video available",
"Check for Replays:": "Check for Replays",
"A thumbnail is required. Please upload or provide an image URL above.": "A thumbnail is required. Please upload or provide an image URL above.",
"You can upload your own recording or select a replay when your stream is over": "You can upload your own recording or select a replay when your stream is over",
"This channel isn't staking enough LBRY Credits for inline image previews.": "This channel isn't staking enough LBRY Credits for inline image previews.",
"Fromage": "Fromage",
@ -1894,6 +1893,7 @@
"Tá Rolando": "Tá Rolando",
"Watch content and earn more Credits for each level unlocked! 10 views required for level 1 (Current Score: 0). Only up to 10 views per day count.": "Watch content and earn more Credits for each level unlocked! 10 views required for level 1 (Current Score: 0). Only up to 10 views per day count.",
"Follow your favorite creators and earn more Credits for each level unlocked! Follow 1 creators for level 1 (Current Score: 0).": "Follow your favorite creators and earn more Credits for each level unlocked! Follow 1 creators for level 1 (Current Score: 0).",
"Video/Audio": "Video/Audio",
"Channel Not Found": "Channel Not Found",
"Probably because you didn't make it.": "Probably because you didn't make it.",
"--end--": "--end--"
}

View file

@ -5,6 +5,7 @@ import ChannelThumbnail from 'component/channelThumbnail';
import { parseURI } from 'lbry-redux';
import ChannelBlockButton from 'component/channelBlockButton';
import ChannelMuteButton from 'component/channelMuteButton';
import SubscribeButton from 'component/subscribeButton';
type Props = {
uri: string,
@ -30,6 +31,7 @@ function AbandonedChannelPreview(props: Props) {
<div className="section__actions">
<ChannelBlockButton uri={uri} />
<ChannelMuteButton uri={uri} />
<SubscribeButton uri={uri} />
</div>
</div>
</div>

View file

@ -15,13 +15,14 @@ type SubscriptionArgs = {
type Props = {
permanentUrl: ?string,
isSubscribed: boolean,
doChannelSubscribe: SubscriptionArgs => void,
doChannelUnsubscribe: SubscriptionArgs => void,
doChannelSubscribe: (SubscriptionArgs) => void,
doChannelUnsubscribe: (SubscriptionArgs) => void,
showSnackBarOnSubscribe: boolean,
doToast: ({ message: string }) => void,
shrinkOnMobile: boolean,
notificationsDisabled: boolean,
user: ?User,
uri: string,
};
export default function SubscribeButton(props: Props) {
@ -35,6 +36,7 @@ export default function SubscribeButton(props: Props) {
shrinkOnMobile = false,
notificationsDisabled,
user,
uri,
} = props;
const buttonRef = useRef();
@ -43,6 +45,7 @@ export default function SubscribeButton(props: Props) {
isHovering = isMobile ? true : isHovering;
const uiNotificationsEnabled = user && user.experimental_ui;
const { channelName: rawChannelName } = parseURI(uri);
const { channelName } = parseURI(permanentUrl);
const claimName = '@' + channelName;
@ -55,6 +58,32 @@ export default function SubscribeButton(props: Props) {
const label = isMobile && shrinkOnMobile ? '' : unfollowOverride || subscriptionLabel;
const titlePrefix = isSubscribed ? __('Unfollow this channel') : __('Follow this channel');
if (isSubscribed && !permanentUrl && rawChannelName) {
return (
<div className="button-group">
<Button
ref={buttonRef}
iconColor="red"
largestLabel={isMobile && shrinkOnMobile ? '' : subscriptionLabel}
icon={ICONS.UNSUBSCRIBE}
button={'alt'}
requiresAuth={IS_WEB}
label={label}
title={titlePrefix}
onClick={(e) => {
e.stopPropagation();
subscriptionHandler({
channelName: '@' + rawChannelName,
uri: uri,
notificationsDisabled: true,
});
}}
/>
</div>
);
}
return permanentUrl ? (
<div className="button-group">
<Button
@ -66,7 +95,7 @@ export default function SubscribeButton(props: Props) {
requiresAuth={IS_WEB}
label={label}
title={titlePrefix}
onClick={e => {
onClick={(e) => {
e.stopPropagation();
subscriptionHandler({

View file

@ -17,18 +17,18 @@ export default handleActions(
const newSubscriptions: Array<Subscription> = state.subscriptions.slice();
let newFollowing: Array<Following> = state.following.slice();
// prevent duplicates in the sidebar
if (!newSubscriptions.some(sub => sub.uri === newSubscription.uri)) {
if (!newSubscriptions.some((sub) => sub.uri === newSubscription.uri)) {
// $FlowFixMe
newSubscriptions.unshift(newSubscription);
}
if (!newFollowing.some(sub => sub.uri === newSubscription.uri)) {
if (!newFollowing.some((sub) => sub.uri === newSubscription.uri)) {
newFollowing.unshift({
uri: newSubscription.uri,
notificationsDisabled: newSubscription.notificationsDisabled,
});
} else {
newFollowing = newFollowing.map(following => {
newFollowing = newFollowing.map((following) => {
if (following.uri === newSubscription.uri) {
return {
uri: newSubscription.uri,
@ -50,10 +50,12 @@ export default handleActions(
const subscriptionToRemove: Subscription = action.data;
const newSubscriptions = state.subscriptions
.slice()
.filter(subscription => subscription.channelName !== subscriptionToRemove.channelName);
.filter(
(subscription) => subscription.channelName.toLowerCase() !== subscriptionToRemove.channelName.toLowerCase()
);
const newFollowing = state.following
.slice()
.filter(subscription => subscription.uri !== subscriptionToRemove.uri);
.filter((subscription) => subscription.uri !== subscriptionToRemove.uri);
return {
...state,
@ -95,7 +97,7 @@ export default handleActions(
if (!subscriptions) {
newSubscriptions = state.subscriptions;
} else {
const parsedSubscriptions = subscriptions.map(uri => {
const parsedSubscriptions = subscriptions.map((uri) => {
const { channelName } = parseURI(uri);
return {

View file

@ -9,25 +9,25 @@ import {
import { swapKeyAndValue } from 'util/swap-json';
// Returns the entire subscriptions state
const selectState = state => state.subscriptions || {};
const selectState = (state) => state.subscriptions || {};
// Returns the list of channel uris a user is subscribed to
export const selectSubscriptions = createSelector(
selectState,
state => state.subscriptions && state.subscriptions.sort((a, b) => a.channelName.localeCompare(b.channelName))
(state) => state.subscriptions && state.subscriptions.sort((a, b) => a.channelName.localeCompare(b.channelName))
);
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
export const selectIsFetchingSubscriptions = createSelector(selectState, state => state.loading);
export const selectIsFetchingSubscriptions = createSelector(selectState, (state) => state.loading);
// The current view mode on the subscriptions page
export const selectViewMode = createSelector(selectState, state => state.viewMode);
export const selectViewMode = createSelector(selectState, (state) => state.viewMode);
// Suggested subscriptions from internal apis
export const selectSuggested = createSelector(selectState, state => state.suggested);
export const selectIsFetchingSuggested = createSelector(selectState, state => state.loadingSuggested);
export const selectSuggested = createSelector(selectState, (state) => state.suggested);
export const selectIsFetchingSuggested = createSelector(selectState, (state) => state.loadingSuggested);
export const selectSuggestedChannels = createSelector(
selectSubscriptions,
selectSuggested,
@ -55,7 +55,7 @@ export const selectSuggestedChannels = createSelector(
// If a uri isn't already in the suggested object, add it
const suggestedChannels = { ...topSubscribedSuggestions };
Object.keys(featuredSuggestions).forEach(uri => {
Object.keys(featuredSuggestions).forEach((uri) => {
if (!suggestedChannels[uri]) {
const channelLabel = featuredSuggestions[uri];
suggestedChannels[uri] = channelLabel;
@ -73,15 +73,15 @@ export const selectSuggestedChannels = createSelector(
}
});
return Object.keys(suggestedChannels).map(uri => ({
return Object.keys(suggestedChannels).map((uri) => ({
uri,
label: suggestedChannels[uri],
}));
}
);
export const selectFirstRunCompleted = createSelector(selectState, state => state.firstRunCompleted);
export const selectshowSuggestedSubs = createSelector(selectState, state => state.showSuggestedSubs);
export const selectFirstRunCompleted = createSelector(selectState, (state) => state.firstRunCompleted);
export const selectshowSuggestedSubs = createSelector(selectState, (state) => state.showSuggestedSubs);
// Fetching any claims that are a part of a users subscriptions
export const selectSubscriptionsBeingFetched = createSelector(
@ -89,7 +89,7 @@ export const selectSubscriptionsBeingFetched = createSelector(
selectAllFetchingChannelClaims,
(subscriptions, fetchingChannelClaims) => {
const fetchingSubscriptionMap = {};
subscriptions.forEach(sub => {
subscriptions.forEach((sub) => {
const isFetching = fetchingChannelClaims && fetchingChannelClaims[sub.uri];
if (isFetching) {
fetchingSubscriptionMap[sub.uri] = true;
@ -102,17 +102,17 @@ export const selectSubscriptionsBeingFetched = createSelector(
// Returns true if a user is subscribed to the channel associated with the uri passed in
// Accepts content or channel uris
export const makeSelectChannelInSubscriptions = uri =>
createSelector(selectSubscriptions, subscriptions => subscriptions.some(sub => sub.uri === uri));
export const makeSelectChannelInSubscriptions = (uri) =>
createSelector(selectSubscriptions, (subscriptions) => subscriptions.some((sub) => sub.uri === uri));
export const makeSelectIsSubscribed = uri =>
export const makeSelectIsSubscribed = (uri) =>
createSelector(
selectSubscriptions,
makeSelectChannelForClaimUri(uri, true),
makeSelectClaimForUri(uri),
(subscriptions, channelUri, claim) => {
if (channelUri) {
return subscriptions.some(sub => sub.uri === channelUri);
return subscriptions.some((sub) => sub.uri === channelUri);
}
// If we couldn't get a channel uri from the claim uri, the uri passed in might be a channel already
@ -123,21 +123,25 @@ export const makeSelectIsSubscribed = uri =>
if (isChannel && claim) {
const uri = claim.permanent_url;
return subscriptions.some(sub => sub.uri === uri);
return subscriptions.some((sub) => sub.uri === uri);
}
if (isChannel && !claim) {
return subscriptions.some((sub) => sub.uri === uri);
}
return false;
}
);
export const makeSelectNotificationsDisabled = uri =>
export const makeSelectNotificationsDisabled = (uri) =>
createSelector(
selectFollowing,
makeSelectChannelForClaimUri(uri, true),
makeSelectClaimForUri(uri),
(following, channelUri, claim) => {
if (channelUri) {
return following.some(following => following.uri === channelUri && following.notificationsDisabled);
return following.some((following) => following.uri === channelUri && following.notificationsDisabled);
}
// If we couldn't get a channel uri from the claim uri, the uri passed in might be a channel already
@ -148,7 +152,7 @@ export const makeSelectNotificationsDisabled = uri =>
if (isChannel && claim) {
const uri = claim.permanent_url;
const disabled = following.some(sub => {
const disabled = following.some((sub) => {
return sub.uri === uri && sub.notificationsDisabled === true;
});