diff --git a/src/ui/component/claimTags/view.jsx b/src/ui/component/claimTags/view.jsx
index 8a64e8750..dde5d7382 100644
--- a/src/ui/component/claimTags/view.jsx
+++ b/src/ui/component/claimTags/view.jsx
@@ -1,7 +1,7 @@
// @flow
import * as React from 'react';
import classnames from 'classnames';
-import Button from 'component/button';
+import Tag from 'component/tag';
const SLIM_TAGS = 1;
const NORMAL_TAGS = 4;
@@ -45,7 +45,7 @@ export default function ClaimTags(props: Props) {
return (
{tagsToDisplay.map(tag => (
-
+
))}
);
diff --git a/src/ui/component/common/credit-amount.jsx b/src/ui/component/common/credit-amount.jsx
index 5af75e353..a8df18839 100644
--- a/src/ui/component/common/credit-amount.jsx
+++ b/src/ui/component/common/credit-amount.jsx
@@ -44,7 +44,7 @@ class CreditAmount extends React.PureComponent {
let amountText;
if (showFree && isFree) {
- amountText = __('FREE');
+ amountText = __('Free');
} else {
amountText = formattedAmount;
diff --git a/src/ui/component/publishForm/view.jsx b/src/ui/component/publishForm/view.jsx
index c97fd0bc9..ddca4b98d 100644
--- a/src/ui/component/publishForm/view.jsx
+++ b/src/ui/component/publishForm/view.jsx
@@ -132,6 +132,7 @@ function PublishForm(props: Props) {
updatePublishForm({ tags: [...tags, tag] })}
diff --git a/src/ui/component/tag/view.jsx b/src/ui/component/tag/view.jsx
index f16d52f9b..b47050e6d 100644
--- a/src/ui/component/tag/view.jsx
+++ b/src/ui/component/tag/view.jsx
@@ -2,6 +2,7 @@
import * as ICONS from 'constants/icons';
import React from 'react';
import classnames from 'classnames';
+import { MATURE_TAGS } from 'lbry-redux';
import Button from 'component/button';
type Props = {
@@ -13,8 +14,9 @@ type Props = {
export default function Tag(props: Props) {
const { name, onClick, type = 'link', disabled = false } = props;
-
+ const isMature = MATURE_TAGS.includes(name);
const clickProps = onClick ? { onClick } : { navigate: `/$/tags?t=${name}` };
+
let title;
if (!onClick) {
title = __('View tag');
@@ -28,8 +30,10 @@ export default function Tag(props: Props) {
disabled={disabled}
title={title}
className={classnames('tag', {
- 'tag--add': type === 'add',
'tag--remove': type === 'remove',
+ // tag--add only adjusts the color, which causes issues with mature tag color clashing
+ 'tag--add': !isMature && type === 'add',
+ 'tag--mature': isMature,
})}
label={name}
iconSize={12}
diff --git a/src/ui/component/tagsSearch/view.jsx b/src/ui/component/tagsSearch/view.jsx
index 0fef53f8a..10cf3cdb3 100644
--- a/src/ui/component/tagsSearch/view.jsx
+++ b/src/ui/component/tagsSearch/view.jsx
@@ -16,10 +16,11 @@ type Props = {
doToggleTagFollow: string => void,
doAddTag: string => void,
onSelect?: Tag => void,
+ suggestMature?: boolean,
};
export default function TagSelect(props: Props) {
- const { unfollowedTags = [], followedTags = [], doToggleTagFollow, doAddTag, onSelect } = props;
+ const { unfollowedTags = [], followedTags = [], doToggleTagFollow, doAddTag, onSelect, suggestMature } = props;
const [newTag, setNewTag] = useState('');
let tags = unfollowedTags.slice();
@@ -34,6 +35,10 @@ export default function TagSelect(props: Props) {
.filter(doesTagMatch)
.slice(0, 5);
+ if (!newTag && suggestMature) {
+ suggestedTags.push('mature');
+ }
+
const suggestedTransitions = useTransition(suggestedTags, tag => tag, unfollowedTagsAnimation);
function onChange(e) {
diff --git a/src/ui/component/tagsSelect/view.jsx b/src/ui/component/tagsSelect/view.jsx
index f74d7ec07..92b780942 100644
--- a/src/ui/component/tagsSelect/view.jsx
+++ b/src/ui/component/tagsSelect/view.jsx
@@ -11,6 +11,7 @@ type Props = {
showClose: boolean,
followedTags: Array,
doToggleTagFollow: string => void,
+ suggestMature: boolean,
// Ovverides
// The default component is for following tags
@@ -29,10 +30,22 @@ const tagsAnimation = {
};
export default function TagSelect(props: Props) {
- const { showClose, followedTags, doToggleTagFollow, title, help, empty, tagsChosen, onSelect, onRemove } = props;
+ const {
+ showClose,
+ followedTags,
+ doToggleTagFollow,
+ title,
+ help,
+ empty,
+ tagsChosen,
+ onSelect,
+ onRemove,
+ suggestMature,
+ } = props;
const [hasClosed, setHasClosed] = usePersistedState('tag-select:has-closed', false);
const tagsToDisplay = tagsChosen || followedTags;
const transitions = useTransition(tagsToDisplay, tag => tag.name, tagsAnimation);
+ const hasMatureTag = tagsToDisplay.map(tag => tag.name).includes('mature');
function handleClose() {
setHasClosed(true);
@@ -73,7 +86,7 @@ export default function TagSelect(props: Props) {
{empty || __("You aren't following any tags, try searching for one.")}
)}
-
+
{help !== false && (
{help || __("The tags you follow will change what's trending for you.")}
)}
diff --git a/src/ui/constants/tags.js b/src/ui/constants/tags.js
deleted file mode 100644
index c7f34095a..000000000
--- a/src/ui/constants/tags.js
+++ /dev/null
@@ -1,14 +0,0 @@
-export const defaultFollowedTags = [
- 'blockchain',
- 'news',
- 'learning',
- 'technology',
- 'automotive',
- 'economics',
- 'food',
- 'science',
- 'art',
- 'nature',
-];
-
-export const defaultKnownTags = ['beliefs', 'funny', 'gaming', 'pop culture', 'music', 'sports', 'weapons'];
diff --git a/src/ui/page/file/view.jsx b/src/ui/page/file/view.jsx
index e3117f97a..f9c4a52db 100644
--- a/src/ui/page/file/view.jsx
+++ b/src/ui/page/file/view.jsx
@@ -312,7 +312,7 @@ class FilePage extends React.Component {
/>
{isRewardContent &&
}
- {nsfw &&
MATURE
}
+ {nsfw &&
{__('Mature')}
}
diff --git a/src/ui/reducers.js b/src/ui/reducers.js
index f60b713ff..43e83882a 100644
--- a/src/ui/reducers.js
+++ b/src/ui/reducers.js
@@ -6,7 +6,7 @@ import {
searchReducer,
walletReducer,
notificationsReducer,
- tagsReducerBuilder,
+ tagsReducer,
commentReducer,
} from 'lbry-redux';
import { userReducer, rewardsReducer, costInfoReducer, blacklistReducer, homepageReducer, statsReducer } from 'lbryinc';
@@ -16,17 +16,6 @@ import contentReducer from 'redux/reducers/content';
import settingsReducer from 'redux/reducers/settings';
import subscriptionsReducer from 'redux/reducers/subscriptions';
import publishReducer from 'redux/reducers/publish';
-import { defaultKnownTags, defaultFollowedTags } from 'constants/tags';
-
-function getDefaultKnownTags() {
- return defaultFollowedTags.concat(defaultKnownTags).reduce(
- (tagsMap, tag) => ({
- ...tagsMap,
- [tag]: { name: tag },
- }),
- {}
- );
-}
export default history =>
combineReducers({
@@ -47,7 +36,7 @@ export default history =>
settings: settingsReducer,
stats: statsReducer,
subscriptions: subscriptionsReducer,
- tags: tagsReducerBuilder({ followedTags: defaultFollowedTags, knownTags: getDefaultKnownTags() }),
+ tags: tagsReducer,
user: userReducer,
wallet: walletReducer,
});
diff --git a/src/ui/redux/actions/publish.js b/src/ui/redux/actions/publish.js
index 663d26c7d..b09f2d017 100644
--- a/src/ui/redux/actions/publish.js
+++ b/src/ui/redux/actions/publish.js
@@ -155,6 +155,7 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis
license_url: licenseUrl,
thumbnail,
title,
+ tags,
} = value;
const publishData: UpdatePublishFormData = {
@@ -171,6 +172,7 @@ export const doPrepareEdit = (claim: StreamClaim, uri: string, fileInfo: FileLis
uploadThumbnailStatus: thumbnail ? THUMBNAIL_STATUSES.MANUAL : undefined,
licenseUrl,
nsfw: isClaimNsfw(claim),
+ tags: tags ? tags.map(tag => ({ name: tag })) : [],
};
if (channelName) {
diff --git a/src/ui/scss/component/_badge.scss b/src/ui/scss/component/_badge.scss
index 4ca0e8ba6..e320d5daf 100644
--- a/src/ui/scss/component/_badge.scss
+++ b/src/ui/scss/component/_badge.scss
@@ -19,3 +19,12 @@
background-color: $lbry-red-2;
color: $lbry-white;
}
+
+.badge--mature {
+ background-color: lighten($lbry-grape-1, 10%);
+ color: $lbry-black;
+
+ svg {
+ stroke: $lbry-black;
+ }
+}
diff --git a/src/ui/scss/component/_tags.scss b/src/ui/scss/component/_tags.scss
index 17db46b35..8dd2c4e89 100644
--- a/src/ui/scss/component/_tags.scss
+++ b/src/ui/scss/component/_tags.scss
@@ -34,6 +34,7 @@ $main: $lbry-teal-5;
}
.tag {
+ @extend .badge;
@extend .badge--tag;
user-select: none;
cursor: pointer;
@@ -61,12 +62,20 @@ $main: $lbry-teal-5;
}
.tag--remove {
- @extend .tag;
max-width: 20rem;
}
.tag--add {
background-color: lighten($lbry-teal-5, 60%);
+
+ &.tag--mature {
+ @extend .badge--mature;
+ }
+}
+
+.tag--mature {
+ @extend .badge--mature;
+ // Lighten the color a little so it doesn't stand out as much on claim previews
}
.tag__action-label {
diff --git a/src/ui/store.js b/src/ui/store.js
index 0b48beaa8..7d3b10a51 100644
--- a/src/ui/store.js
+++ b/src/ui/store.js
@@ -74,6 +74,7 @@ const appFilter = createFilter('app', ['hasClickedComment', 'searchOptionsExpand
// We only need to persist the receiveAddress for the wallet
const walletFilter = createFilter('wallet', ['receiveAddress']);
const searchFilter = createFilter('search', ['options']);
+const tagsFilter = createFilter('tags', ['followedTags']);
const whiteListedReducers = [
// @if TARGET='app'
'publish',
@@ -86,6 +87,7 @@ const whiteListedReducers = [
'search',
'tags',
];
+
const persistOptions = {
whitelist: whiteListedReducers,
// Order is important. Needs to be compressed last or other transforms can't
@@ -98,6 +100,7 @@ const persistOptions = {
// @endif
appFilter,
searchFilter,
+ tagsFilter,
compressor,
],
debounce: 5000,