-
Notifications
You must be signed in to change notification settings - Fork 689
Expand file tree
/
Copy pathCommonPlatformFields.tsx
More file actions
158 lines (138 loc) · 5.1 KB
/
Copy pathCommonPlatformFields.tsx
File metadata and controls
158 lines (138 loc) · 5.1 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
import { TPlatform } from '../../../services/platforms';
import { $t } from '../../../services/i18n';
import React, { useMemo } from 'react';
import { InputComponent, TextAreaInput, TextInput, TInputLayout } from '../../shared/inputs';
import { TLayoutMode } from './platforms/PlatformSettingsLayout';
import { Services } from '../../service-provider';
import { Tooltip } from 'antd';
import AnimatedWrapper from 'components-react/shared/AnimatedWrapper';
interface ICommonPlatformSettings {
title: string;
description?: string;
useCustomFields?: boolean;
}
interface IProps {
/**
* if provided then change props only for the provided platform
*/
platform?: TPlatform;
layoutMode?: TLayoutMode;
value: ICommonPlatformSettings;
descriptionIsRequired?: boolean;
enabledPlatforms?: TPlatform[];
layout?: TInputLayout;
onChange: (newValue: ICommonPlatformSettings) => unknown;
}
type TCustomFieldName = 'title' | 'description';
/**
* Component for modifying common platform fields such as "Title" and "Description"
* if "props.platform" is provided it changes props for a single platform
* otherwise it changes props for all enabled platforms
*/
export const CommonPlatformFields = InputComponent((rawProps: IProps) => {
const defaultProps = { layoutMode: 'singlePlatform' as TLayoutMode };
const p: IProps = { ...defaultProps, ...rawProps };
function updatePlatform(patch: Partial<ICommonPlatformSettings>) {
const platformSettings = p.value;
p.onChange({ ...platformSettings, ...patch });
}
function updateCommonField(fieldName: TCustomFieldName, value: string) {
updatePlatform({ [fieldName]: value });
}
const view = Services.StreamingService.views;
const fieldsAreVisible = useMemo(() => {
if (p.layoutMode === 'singlePlatform') return true;
return !p.platform || p.value.useCustomFields || false;
}, [p.layoutMode, p.platform, p.value.useCustomFields]);
const descriptionIsRequired =
typeof p.descriptionIsRequired === 'boolean'
? p.descriptionIsRequired
: p.platform === 'facebook';
const hasDescription = p.platform
? view.supports('description', [p.platform as TPlatform])
: view.supports('description');
// Only the shared instance can run out of platforms to write to, and only while live, where
// `updateCommonFields` skips any platform using its own title. Once every enabled platform has
// opted out, editing the shared title changes nothing.
const titleDisabled =
!p.platform &&
view.isMidStreamMode &&
view.enabledPlatforms.length > 0 &&
!view.platformsWithoutCustomFields.length;
const fields = p.value;
const height = useMemo(() => {
if (!fieldsAreVisible) {
return '0px';
}
if (hasDescription) {
return '162px';
}
return '71px';
}, [fieldsAreVisible, hasDescription]);
// determine max character length for title by enabled platform limitation
let maxCharacters = 120;
const enabledPlatforms = view.enabledPlatforms;
if (enabledPlatforms.includes('youtube')) {
maxCharacters = 100;
} else if (enabledPlatforms.includes('twitch')) {
maxCharacters = 140;
}
// Patreon requires both a title and description of at least 3 characters,
// but other platforms do not have a minimum character requirement for title or description
const hasPatreon = p.platform === 'patreon' || enabledPlatforms.includes('patreon');
const minCharacters = hasPatreon ? 3 : undefined;
const titleTooltip = useMemo(() => {
if (hasPatreon) {
return $t('Patreon requires a title of at least 3 characters');
}
if (enabledPlatforms.includes('tiktok')) {
return $t('Only 32 characters of your title will display on TikTok');
}
return undefined;
}, [enabledPlatforms]);
return (
<AnimatedWrapper
visible={fieldsAreVisible}
style={{ marginBottom: p.platform && fieldsAreVisible ? '10px' : '0px' }}
height={height}
>
{/*TITLE*/}
<TextInput
value={fields['title']}
name="title"
onChange={val => updateCommonField('title', val)}
label={
titleTooltip ? (
<Tooltip title={titleTooltip} placement="right">
{$t('Title')}
<i className="icon-information" style={{ marginLeft: '5px' }} />
</Tooltip>
) : (
$t('Title')
)
}
// A disabled input cannot be corrected, so it must not be able to fail validation. Each
// platform using its own title validates that title in its own section.
required={!titleDisabled}
disabled={titleDisabled}
max={maxCharacters}
min={minCharacters}
layout={p.layout}
style={{ marginTop: !p.platform ? '0px' : '10px' }}
size="large"
/>
{/*DESCRIPTION*/}
{hasDescription && (
<TextAreaInput
value={fields['description']}
onChange={val => updateCommonField('description', val)}
name="description"
label={$t('Description')}
required={descriptionIsRequired}
min={minCharacters}
layout={p.layout}
/>
)}
</AnimatedWrapper>
);
});