feat: more channels
This commit is contained in:
parent
e51906d485
commit
d2ba83d0b1
|
|
@ -45,6 +45,7 @@ import {
|
|||
PostToOrganization,
|
||||
} from '@gitroom/frontend/components/launches/post.to.organization';
|
||||
import { Submitted } from '@gitroom/frontend/components/launches/submitted';
|
||||
import { capitalize } from 'lodash';
|
||||
|
||||
export const AddEditModal: FC<{
|
||||
date: dayjs.Dayjs;
|
||||
|
|
@ -241,6 +242,7 @@ export const AddEditModal: FC<{
|
|||
}
|
||||
|
||||
const values = getValues();
|
||||
|
||||
const allKeys = Object.keys(values).map((v) => ({
|
||||
integration: integrations.find((p) => p.id === v),
|
||||
value: values[v].posts,
|
||||
|
|
@ -248,9 +250,46 @@ export const AddEditModal: FC<{
|
|||
group: existingData?.group,
|
||||
trigger: values[v].trigger,
|
||||
settings: values[v].settings(),
|
||||
firstCommentRequirements: values[v].firstCommentRequirements,
|
||||
maximumMediaRequirements: values[v].maximumMediaRequirements,
|
||||
minimumMediaRequirements: values[v].minimumMediaRequirements,
|
||||
}));
|
||||
|
||||
for (const key of allKeys) {
|
||||
// @ts-ignore
|
||||
const images = key?.value[0].image;
|
||||
if (
|
||||
(images?.length || 0) > (key.maximumMediaRequirements || 0) ||
|
||||
(images?.length || 0) < (key.minimumMediaRequirements || 0)
|
||||
) {
|
||||
toaster.show(
|
||||
`The amount of ${capitalize(key?.integration?.identifier)} media attached supposed to be ${
|
||||
key.maximumMediaRequirements === key.minimumMediaRequirements
|
||||
? key.minimumMediaRequirements
|
||||
: `between ${key.minimumMediaRequirements} to ${key.maximumMediaRequirements}`
|
||||
}`,
|
||||
'warning'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (
|
||||
key.firstCommentRequirements &&
|
||||
!images?.every((p: any) =>
|
||||
key.firstCommentRequirements === 'video'
|
||||
? p.name.includes('mp4')
|
||||
: !p.name.includes('mp4')
|
||||
)
|
||||
) {
|
||||
toaster.show(
|
||||
`${capitalize(key?.integration?.identifier?.toUpperCase())} media should be a ${
|
||||
key.firstCommentRequirements === 'video' ? 'video' : 'image'
|
||||
}`,
|
||||
'warning'
|
||||
);
|
||||
return;
|
||||
}
|
||||
|
||||
if (key.value.some((p) => !p.content || p.content.length < 6)) {
|
||||
setShowError(true);
|
||||
return;
|
||||
|
|
@ -346,7 +385,10 @@ export const AddEditModal: FC<{
|
|||
onChange={setSelectedIntegrations}
|
||||
/>
|
||||
)}
|
||||
<div id="renderEditor" className={clsx(!showHide.hideTopEditor && 'hidden')} />
|
||||
<div
|
||||
id="renderEditor"
|
||||
className={clsx(!showHide.hideTopEditor && 'hidden')}
|
||||
/>
|
||||
{!existingData.integration && !showHide.hideTopEditor ? (
|
||||
<>
|
||||
<div>You are in global editing mode</div>
|
||||
|
|
|
|||
|
|
@ -1,11 +1,28 @@
|
|||
import {useEffect, useMemo} from 'react';
|
||||
import {useForm, useFormContext} from 'react-hook-form';
|
||||
import {classValidatorResolver} from "@hookform/resolvers/class-validator";
|
||||
import { useEffect, useMemo } from 'react';
|
||||
import { useForm, useFormContext } from 'react-hook-form';
|
||||
import { classValidatorResolver } from '@hookform/resolvers/class-validator';
|
||||
|
||||
const finalInformation = {} as {
|
||||
[key: string]: { posts: Array<{id?: string, content: string, media?: Array<string>}>; settings: () => object; trigger: () => Promise<boolean>; isValid: boolean };
|
||||
[key: string]: {
|
||||
posts: Array<{ id?: string; content: string; media?: Array<string> }>;
|
||||
settings: () => object;
|
||||
trigger: () => Promise<boolean>;
|
||||
isValid: boolean;
|
||||
firstCommentRequirements?: 'video' | 'image';
|
||||
minimumMediaRequirements?: number;
|
||||
maximumMediaRequirements?: number;
|
||||
};
|
||||
};
|
||||
export const useValues = (initialValues: object, integration: string, identifier: string, value: Array<{id?: string, content: string, media?: Array<string>}>, dto: any) => {
|
||||
export const useValues = (
|
||||
initialValues: object,
|
||||
integration: string,
|
||||
identifier: string,
|
||||
value: Array<{ id?: string; content: string; media?: Array<string> }>,
|
||||
dto: any,
|
||||
firstCommentRequirements?: 'video' | 'image',
|
||||
minimumMediaRequirements?: number,
|
||||
maximumMediaRequirements?: number
|
||||
) => {
|
||||
const resolver = useMemo(() => {
|
||||
return classValidatorResolver(dto);
|
||||
}, [integration]);
|
||||
|
|
@ -18,15 +35,28 @@ export const useValues = (initialValues: object, integration: string, identifier
|
|||
});
|
||||
|
||||
const getValues = useMemo(() => {
|
||||
return () => ({...form.getValues(), __type: identifier});
|
||||
return () => ({ ...form.getValues(), __type: identifier });
|
||||
}, [form, integration]);
|
||||
|
||||
finalInformation[integration]= finalInformation[integration] || {};
|
||||
finalInformation[integration] = finalInformation[integration] || {};
|
||||
finalInformation[integration].posts = value;
|
||||
finalInformation[integration].isValid = form.formState.isValid;
|
||||
finalInformation[integration].settings = getValues;
|
||||
finalInformation[integration].trigger = form.trigger;
|
||||
|
||||
if (firstCommentRequirements) {
|
||||
finalInformation[integration].firstCommentRequirements =
|
||||
firstCommentRequirements;
|
||||
}
|
||||
if (minimumMediaRequirements) {
|
||||
finalInformation[integration].minimumMediaRequirements =
|
||||
minimumMediaRequirements;
|
||||
}
|
||||
if (maximumMediaRequirements) {
|
||||
finalInformation[integration].maximumMediaRequirements =
|
||||
maximumMediaRequirements;
|
||||
}
|
||||
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
delete finalInformation[integration];
|
||||
|
|
|
|||
|
|
@ -66,7 +66,10 @@ export const EditorWrapper: FC<{ children: ReactNode }> = ({ children }) => {
|
|||
export const withProvider = (
|
||||
SettingsComponent: FC | null,
|
||||
PreviewComponent: FC,
|
||||
dto?: any
|
||||
dto?: any,
|
||||
firstCommentRequirements?: 'video' | 'image',
|
||||
minimumMediaRequirements?: number,
|
||||
maximumMediaRequirements?: number,
|
||||
) => {
|
||||
return (props: {
|
||||
identifier: string;
|
||||
|
|
@ -117,7 +120,10 @@ export const withProvider = (
|
|||
props.id,
|
||||
props.identifier,
|
||||
editInPlace ? InPlaceValue : props.value,
|
||||
dto
|
||||
dto,
|
||||
firstCommentRequirements,
|
||||
minimumMediaRequirements,
|
||||
maximumMediaRequirements
|
||||
);
|
||||
|
||||
// change editor value
|
||||
|
|
|
|||
|
|
@ -109,4 +109,4 @@ const InstagramPreview: FC = (props) => {
|
|||
);
|
||||
};
|
||||
|
||||
export default withProvider(null, InstagramPreview);
|
||||
export default withProvider(null, InstagramPreview, undefined, undefined, 1, 10);
|
||||
|
|
|
|||
|
|
@ -22,6 +22,7 @@ const YoutubeSettings: FC = () => {
|
|||
<MediumTags label="Tags" {...register('tags')} />
|
||||
<div className="mt-[20px]">
|
||||
<MediaComponent
|
||||
type="image"
|
||||
label="Thumbnail"
|
||||
description="Thumbnail picture (optional)"
|
||||
{...register('thumbnail')}
|
||||
|
|
@ -134,5 +135,8 @@ const YoutubePreview: FC = (props) => {
|
|||
export default withProvider(
|
||||
YoutubeSettings,
|
||||
YoutubePreview,
|
||||
YoutubeSettingsDto
|
||||
YoutubeSettingsDto,
|
||||
'video',
|
||||
1,
|
||||
1
|
||||
);
|
||||
|
|
|
|||
|
|
@ -50,9 +50,10 @@ export const showMediaBox = (
|
|||
|
||||
export const MediaBox: FC<{
|
||||
setMedia: (params: { id: string; path: string }) => void;
|
||||
type?: 'image' | 'video';
|
||||
closeModal: () => void;
|
||||
}> = (props) => {
|
||||
const { setMedia, closeModal } = props;
|
||||
const { setMedia, type, closeModal } = props;
|
||||
const [pages, setPages] = useState(0);
|
||||
const [mediaList, setListMedia] = useState<Media[]>([]);
|
||||
const fetch = useFetch();
|
||||
|
|
@ -140,7 +141,13 @@ export const MediaBox: FC<{
|
|||
<input
|
||||
type="file"
|
||||
className="absolute left-0 top-0 w-full h-full opacity-0"
|
||||
accept="image/*,video/mp4"
|
||||
accept={
|
||||
type === 'video'
|
||||
? 'video/mp4'
|
||||
: type === 'image'
|
||||
? 'image/*'
|
||||
: 'image/*,video/mp4'
|
||||
}
|
||||
onChange={uploadMedia}
|
||||
/>
|
||||
<button
|
||||
|
|
@ -207,22 +214,31 @@ export const MediaBox: FC<{
|
|||
</div>
|
||||
</div>
|
||||
)}
|
||||
{mediaList.map((media) => (
|
||||
<div
|
||||
key={media.id}
|
||||
className="w-[200px] h-[200px] border-tableBorder border-2 cursor-pointer"
|
||||
onClick={setNewMedia(media)}
|
||||
>
|
||||
{media.path.indexOf('mp4') > -1 ? (
|
||||
<VideoFrame url={mediaDirectory.set(media.path)} />
|
||||
) : (
|
||||
<img
|
||||
className="w-full h-full object-cover"
|
||||
src={mediaDirectory.set(media.path)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
{mediaList
|
||||
.filter((f) => {
|
||||
if (type === 'video') {
|
||||
return f.path.indexOf('mp4') > -1;
|
||||
} else if (type === 'image') {
|
||||
return f.path.indexOf('mp4') === -1;
|
||||
}
|
||||
return true;
|
||||
})
|
||||
.map((media) => (
|
||||
<div
|
||||
key={media.id}
|
||||
className="w-[200px] h-[200px] border-tableBorder border-2 cursor-pointer"
|
||||
onClick={setNewMedia(media)}
|
||||
>
|
||||
{media.path.indexOf('mp4') > -1 ? (
|
||||
<VideoFrame url={mediaDirectory.set(media.path)} />
|
||||
) : (
|
||||
<img
|
||||
className="w-full h-full object-cover"
|
||||
src={mediaDirectory.set(media.path)}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
@ -340,8 +356,9 @@ export const MediaComponent: FC<{
|
|||
onChange: (event: {
|
||||
target: { name: string; value?: { id: string; path: string } };
|
||||
}) => void;
|
||||
type?: 'image' | 'video';
|
||||
}> = (props) => {
|
||||
const { name, label, description, onChange, value } = props;
|
||||
const { name, type, label, description, onChange, value } = props;
|
||||
const { getValues } = useSettings();
|
||||
useEffect(() => {
|
||||
const settings = getValues()[props.name];
|
||||
|
|
@ -369,7 +386,9 @@ export const MediaComponent: FC<{
|
|||
|
||||
return (
|
||||
<div className="flex flex-col gap-[8px]">
|
||||
{modal && <MediaBox setMedia={changeMedia} closeModal={showModal} />}
|
||||
{modal && (
|
||||
<MediaBox setMedia={changeMedia} closeModal={showModal} type={type} />
|
||||
)}
|
||||
<div className="text-[14px]">{label}</div>
|
||||
<div className="text-[12px]">{description}</div>
|
||||
{!!currentMedia && (
|
||||
|
|
|
|||
Loading…
Reference in New Issue