2021-04-21 11:25:06 +02:00
// @flow
import * as React from 'react' ;
import Card from 'component/common/card' ;
import TagsSearch from 'component/tagsSearch' ;
import Page from 'component/page' ;
import ChannelSelector from 'component/channelSelector' ;
import Spinner from 'component/spinner' ;
import { FormField } from 'component/common/form-components/form-field' ;
import LbcSymbol from 'component/common/lbc-symbol' ;
import I18nMessage from 'component/i18nMessage' ;
const DEBOUNCE _REFRESH _MS = 1000 ;
2021-05-25 03:31:59 +02:00
const FEATURE _IS _READY = false ;
2021-04-21 11:25:06 +02:00
type Props = {
activeChannelClaim : ChannelClaim ,
settingsByChannelId : { [ string ] : PerChannelSettings } ,
fetchingCreatorSettings : boolean ,
fetchingBlockedWords : boolean ,
commentBlockWords : ( ChannelClaim , Array < string > ) => void ,
commentUnblockWords : ( ChannelClaim , Array < string > ) => void ,
fetchCreatorSettings : ( Array < string > ) => void ,
updateCreatorSettings : ( ChannelClaim , PerChannelSettings ) => void ,
} ;
export default function SettingsCreatorPage ( props : Props ) {
const {
activeChannelClaim ,
settingsByChannelId ,
commentBlockWords ,
commentUnblockWords ,
fetchCreatorSettings ,
updateCreatorSettings ,
} = props ;
const [ commentsEnabled , setCommentsEnabled ] = React . useState ( true ) ;
const [ mutedWordTags , setMutedWordTags ] = React . useState ( [ ] ) ;
const [ minTipAmountComment , setMinTipAmountComment ] = React . useState ( 0 ) ;
const [ minTipAmountSuperChat , setMinTipAmountSuperChat ] = React . useState ( 0 ) ;
const [ slowModeMinGap , setSlowModeMinGap ] = React . useState ( 0 ) ;
const [ lastUpdated , setLastUpdated ] = React . useState ( 1 ) ;
function settingsToStates ( settings : PerChannelSettings ) {
if ( settings . comments _enabled !== undefined ) {
setCommentsEnabled ( settings . comments _enabled ) ;
}
if ( settings . min _tip _amount _comment !== undefined ) {
setMinTipAmountComment ( settings . min _tip _amount _comment ) ;
}
if ( settings . min _tip _amount _super _chat !== undefined ) {
setMinTipAmountSuperChat ( settings . min _tip _amount _super _chat ) ;
}
if ( settings . slow _mode _min _gap !== undefined ) {
setSlowModeMinGap ( settings . slow _mode _min _gap ) ;
}
if ( settings . words ) {
const tagArray = Array . from ( new Set ( settings . words ) ) ;
setMutedWordTags (
tagArray
. filter ( ( t ) => t !== '' )
. map ( ( x ) => {
return { name : x } ;
} )
) ;
}
}
function setSettings ( newSettings : PerChannelSettings ) {
settingsToStates ( newSettings ) ;
updateCreatorSettings ( activeChannelClaim , newSettings ) ;
setLastUpdated ( Date . now ( ) ) ;
}
function addMutedWords ( newTags : Array < Tag > ) {
const validatedNewTags = [ ] ;
newTags . forEach ( ( newTag ) => {
if ( ! mutedWordTags . some ( ( tag ) => tag . name === newTag . name ) ) {
validatedNewTags . push ( newTag ) ;
}
} ) ;
if ( validatedNewTags . length !== 0 ) {
setMutedWordTags ( [ ... mutedWordTags , ... validatedNewTags ] ) ;
commentBlockWords (
activeChannelClaim ,
validatedNewTags . map ( ( x ) => x . name )
) ;
setLastUpdated ( Date . now ( ) ) ;
}
}
function removeMutedWord ( tagToRemove : Tag ) {
const newMutedWordTags = mutedWordTags . slice ( ) . filter ( ( t ) => t . name !== tagToRemove . name ) ;
setMutedWordTags ( newMutedWordTags ) ;
commentUnblockWords ( activeChannelClaim , [ '' , tagToRemove . name ] ) ;
setLastUpdated ( Date . now ( ) ) ;
}
// Update local states with data from API.
React . useEffect ( ( ) => {
if ( lastUpdated !== 0 && Date . now ( ) - lastUpdated < DEBOUNCE _REFRESH _MS ) {
// Still debouncing. Skip update.
return ;
}
if ( activeChannelClaim && settingsByChannelId && settingsByChannelId [ activeChannelClaim . claim _id ] ) {
const channelSettings = settingsByChannelId [ activeChannelClaim . claim _id ] ;
settingsToStates ( channelSettings ) ;
}
} , [ activeChannelClaim , settingsByChannelId , lastUpdated ] ) ;
// Re-sync list, mainly to correct any invalid settings.
React . useEffect ( ( ) => {
if ( lastUpdated && activeChannelClaim ) {
const timer = setTimeout ( ( ) => {
fetchCreatorSettings ( [ activeChannelClaim . claim _id ] ) ;
} , DEBOUNCE _REFRESH _MS ) ;
return ( ) => clearTimeout ( timer ) ;
}
} , [ lastUpdated , activeChannelClaim , fetchCreatorSettings ] ) ;
2021-05-25 04:58:42 +02:00
const isBusy =
! activeChannelClaim || ! settingsByChannelId || settingsByChannelId [ activeChannelClaim . claim _id ] === undefined ;
const isDisabled =
activeChannelClaim && settingsByChannelId && settingsByChannelId [ activeChannelClaim . claim _id ] === null ;
2021-04-21 11:25:06 +02:00
return (
< Page
noFooter
noSideNavigation
backout = { {
title : _ _ ( 'Creator settings' ) ,
backLabel : _ _ ( 'Done' ) ,
} }
className = "card-stack"
>
< ChannelSelector hideAnon / >
{ isBusy && (
< div className = "main--empty" >
< Spinner / >
< / div >
) }
2021-05-25 04:58:42 +02:00
{ isDisabled && (
< Card
title = { _ _ ( 'Settings unavailable for this channel' ) }
subtitle = { _ _ ( "This channel isn't staking enough LBRY Credits to enable Creator Settings." ) }
/ >
) }
{ ! isBusy && ! isDisabled && (
2021-04-21 11:25:06 +02:00
< >
2021-05-25 03:31:59 +02:00
{ FEATURE _IS _READY && (
< Card
title = { _ _ ( 'General' ) }
actions = {
< >
< FormField
type = "checkbox"
name = "comments_enabled"
label = { _ _ ( 'Enable comments for channel.' ) }
checked = { commentsEnabled }
onChange = { ( ) => setSettings ( { comments _enabled : ! commentsEnabled } ) }
/ >
< FormField
name = "slow_mode_min_gap"
label = { _ _ ( 'Minimum time gap in seconds for Slow Mode in livestream chat.' ) }
min = { 0 }
step = { 1 }
type = "number"
placeholder = "1"
value = { slowModeMinGap }
onChange = { ( e ) => setSettings ( { slow _mode _min _gap : e . target . value } ) }
/ >
< / >
}
/ >
) }
2021-04-21 11:25:06 +02:00
< Card
title = { _ _ ( 'Filter' ) }
actions = {
< div className = "tag--blocked-words" >
< TagsSearch
label = { _ _ ( 'Muted words' ) }
labelAddNew = { _ _ ( 'Add words' ) }
labelSuggestions = { _ _ ( 'Suggestions' ) }
onRemove = { removeMutedWord }
onSelect = { addMutedWords }
disableAutoFocus
tagsPassedIn = { mutedWordTags }
placeholder = { _ _ ( 'Add words to block' ) }
hideSuggestions
2021-05-10 08:31:16 +02:00
disableControlTags
2021-04-21 11:25:06 +02:00
/ >
< / div >
}
/ >
2021-05-25 03:31:59 +02:00
{ FEATURE _IS _READY && (
< Card
title = { _ _ ( 'Tip' ) }
actions = {
< >
< FormField
name = "min_tip_amount_comment"
label = {
< I18nMessage tokens = { { lbc : < LbcSymbol / > } } > Minimum % lbc % tip amount for comments < / I18nMessage >
}
helper = { _ _ (
'Enabling a minimum amount to comment will force all comments, including livestreams, to have tips associated with them. This can help prevent spam.'
) }
className = "form-field--price-amount"
min = { 0 }
step = "any"
type = "number"
placeholder = "1"
value = { minTipAmountComment }
onChange = { ( e ) => setSettings ( { min _tip _amount _comment : parseFloat ( e . target . value ) } ) }
/ >
< FormField
name = "min_tip_amount_super_chat"
label = {
< I18nMessage tokens = { { lbc : < LbcSymbol / > } } > Minimum % lbc % tip amount for hyperchats < / I18nMessage >
}
helper = { _ _ (
'Enabling a minimum amount to hyperchat will force all TIPPED comments to have this value in order to be shown. This still allows regular comments to be posted.'
) }
className = "form-field--price-amount"
min = { 0 }
step = "any"
type = "number"
placeholder = "1"
value = { minTipAmountSuperChat }
onChange = { ( e ) => setSettings ( { min _tip _amount _super _chat : parseFloat ( e . target . value ) } ) }
/ >
< / >
}
/ >
) }
2021-04-21 11:25:06 +02:00
< / >
) }
< / Page >
) ;
}