+ {
+ if (!restricted) {
+ reset();
+ }
+ setRestricted(!restricted);
+ }}
+ description={t`Add restrictions on who can view this post`}
+ />
+ {restricted ? (
+ <>
+
+ {
+ if (
+ !collectToView &&
+ collectModule.type === CollectModules.RevertCollectModule
+ ) {
+ return toast.error(
+ t`Enable collect first to use collect based token gating`
+ );
+ }
+ setCollectToView(!collectToView);
+ }}
+ heading={t`Collectors can view`}
+ description={t`People need to collect it first to be able to view it`}
+ icon={}
+ />
+
+
+ setFollowToView(!followToView)}
+ heading={t`Followers can view`}
+ description={t`People need to follow you to be able to view it`}
+ icon={}
+ />
+
+ >
+ ) : null}
+
+
+
+
+
+ );
+};
+
+export default BasicSettings;
diff --git a/lenster-main/apps/web/src/components/Composer/Actions/AccessSettings/index.tsx b/lenster-main/apps/web/src/components/Composer/Actions/AccessSettings/index.tsx
new file mode 100644
index 0000000..00a2e40
--- /dev/null
+++ b/lenster-main/apps/web/src/components/Composer/Actions/AccessSettings/index.tsx
@@ -0,0 +1,61 @@
+import { LockClosedIcon } from '@heroicons/react/outline';
+import { HelpTooltip, Modal, Tooltip } from '@lenster/ui';
+import { t, Trans } from '@lingui/macro';
+import clsx from 'clsx';
+import { motion } from 'framer-motion';
+import type { FC } from 'react';
+import { useState } from 'react';
+import { useAccessSettingsStore } from 'src/store/access-settings';
+
+import BasicSettings from './BasicSettings';
+
+const AccessSettings: FC = () => {
+ const restricted = useAccessSettingsStore((state) => state.restricted);
+ const hasConditions = useAccessSettingsStore((state) => state.hasConditions);
+ const reset = useAccessSettingsStore((state) => state.reset);
+ const [showModal, setShowModal] = useState(false);
+
+ return (
+ <>
+
+ setShowModal(!showModal)}
+ aria-label="Access"
+ >
+
+
+
+
+
+ Access settings
+
+
+
+ }
+ icon={}
+ show={showModal}
+ onClose={() => {
+ setShowModal(false);
+ if (!hasConditions()) {
+ reset();
+ }
+ }}
+ >
+
+
+ >
+ );
+};
+
+export default AccessSettings;
diff --git a/lenster-main/apps/web/src/components/Composer/Actions/Attachment.tsx b/lenster-main/apps/web/src/components/Composer/Actions/Attachment.tsx
new file mode 100644
index 0000000..07a8016
--- /dev/null
+++ b/lenster-main/apps/web/src/components/Composer/Actions/Attachment.tsx
@@ -0,0 +1,172 @@
+import MenuTransition from '@components/Shared/MenuTransition';
+import { Menu } from '@headlessui/react';
+import {
+ MusicNoteIcon,
+ PhotographIcon,
+ VideoCameraIcon
+} from '@heroicons/react/outline';
+import {
+ ALLOWED_AUDIO_TYPES,
+ ALLOWED_IMAGE_TYPES,
+ ALLOWED_MEDIA_TYPES,
+ ALLOWED_VIDEO_TYPES
+} from '@lenster/data/constants';
+import { Spinner, Tooltip } from '@lenster/ui';
+import { t } from '@lingui/macro';
+import clsx from 'clsx';
+import type { ChangeEvent, FC } from 'react';
+import { Fragment, useId, useRef, useState } from 'react';
+import toast from 'react-hot-toast';
+import useUploadAttachments from 'src/hooks/useUploadAttachments';
+import { usePublicationStore } from 'src/store/publication';
+import { useOnClickOutside } from 'usehooks-ts';
+const Attachment: FC = () => {
+ const attachments = usePublicationStore((state) => state.attachments);
+ const isUploading = usePublicationStore((state) => state.isUploading);
+ const { handleUploadAttachments } = useUploadAttachments();
+ const [showMenu, setShowMenu] = useState(false);
+ const id = useId();
+ const dropdownRef = useRef(null);
+
+ useOnClickOutside(dropdownRef, () => setShowMenu(false));
+
+ const isTypeAllowed = (files: FileList) => {
+ for (const file of files) {
+ if (ALLOWED_MEDIA_TYPES.includes(file.type)) {
+ return true;
+ }
+ }
+
+ return false;
+ };
+
+ const isUploadAllowed = (files: FileList) => {
+ if (files[0]?.type.slice(0, 5) === 'image') {
+ return attachments.length + files.length <= 4;
+ } else {
+ return files.length === 1;
+ }
+ };
+
+ const disableImageUpload = () => {
+ const notImage =
+ attachments[0] &&
+ attachments[0].original.mimeType.slice(0, 5) !== 'image';
+ const isLimit = !notImage && attachments.length >= 4;
+ return notImage || isLimit;
+ };
+
+ const handleAttachment = async (evt: ChangeEvent) => {
+ evt.preventDefault();
+ setShowMenu(false);
+
+ try {
+ const { files } = evt.target;
+ if (!isUploadAllowed(files as FileList)) {
+ toast.error(t`Exceeded max limit of 1 audio, or 1 video, or 4 images`);
+ return;
+ }
+ if (isTypeAllowed(files as FileList)) {
+ await handleUploadAttachments(files);
+ evt.target.value = '';
+ } else {
+ return toast.error(t`File format not allowed.`);
+ }
+ } catch {
+ toast.error(t`Something went wrong while uploading!`);
+ }
+ };
+
+ return (
+
+ );
+};
+
+export default Attachment;
diff --git a/lenster-main/apps/web/src/components/Composer/Actions/CollectSettings/AmountConfig.tsx b/lenster-main/apps/web/src/components/Composer/Actions/CollectSettings/AmountConfig.tsx
new file mode 100644
index 0000000..f4e253b
--- /dev/null
+++ b/lenster-main/apps/web/src/components/Composer/Actions/CollectSettings/AmountConfig.tsx
@@ -0,0 +1,96 @@
+import ToggleWithHelper from '@components/Shared/ToggleWithHelper';
+import { CurrencyDollarIcon } from '@heroicons/react/outline';
+import { DEFAULT_COLLECT_TOKEN } from '@lenster/data/constants';
+import type { Erc20 } from '@lenster/lens';
+import { CollectModules } from '@lenster/lens';
+import { Input } from '@lenster/ui';
+import { t, Trans } from '@lingui/macro';
+import type { FC } from 'react';
+import { useCollectModuleStore } from 'src/store/collect-module';
+
+interface AmountConfigProps {
+ enabledModuleCurrencies?: Erc20[];
+ setCollectType: (data: any) => void;
+}
+
+const AmountConfig: FC = ({
+ enabledModuleCurrencies,
+ setCollectType
+}) => {
+ const collectModule = useCollectModuleStore((state) => state.collectModule);
+
+ return (
+