Skip to content

Commit

Permalink
chore!: remove ipfs dependencies (#167)
Browse files Browse the repository at this point in the history
---------

Signed-off-by: Joseph Chalabi <[email protected]>
Co-authored-by: Felix C. Morency <[email protected]>
  • Loading branch information
chalabi2 and fmorency authored Jan 7, 2025
1 parent cea04ac commit 567ec47
Show file tree
Hide file tree
Showing 13 changed files with 259 additions and 317 deletions.
33 changes: 27 additions & 6 deletions components/groups/components/myGroups.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -54,9 +54,16 @@ export function YourGroups({
const router = useRouter();
const { address } = useChain('manifest');

const filteredGroups = groups.groups.filter(group =>
(group.ipfsMetadata?.title || 'Untitled Group').toLowerCase().includes(searchTerm.toLowerCase())
);
const filteredGroups = groups.groups.filter(group => {
try {
const metadata = group.metadata ? JSON.parse(group.metadata) : null;
const groupTitle = metadata?.title || 'Untitled Group';
return groupTitle.toLowerCase().includes(searchTerm.toLowerCase());
} catch (e) {
console.warn('Failed to parse group metadata:', e);
return 'Untitled Group'.toLowerCase().includes(searchTerm.toLowerCase());
}
});

const totalPages = Math.ceil(filteredGroups.length / pageSize);
const paginatedGroups = filteredGroups.slice(
Expand All @@ -72,9 +79,18 @@ export function YourGroups({
g => g.policies && g.policies.length > 0 && g.policies[0]?.address === policyAddress
);
if (group) {
let groupName = 'Untitled Group';
try {
const metadata = group.metadata ? JSON.parse(group.metadata) : null;
groupName = metadata?.title ?? 'Untitled Group';
} catch (e) {
// If JSON parsing fails, fall back to default name
console.warn('Failed to parse group metadata:', e);
}

setSelectedGroup({
policyAddress,
name: group.ipfsMetadata?.title ?? 'Untitled Group',
name: groupName,
threshold:
(group.policies[0]?.decision_policy as ThresholdDecisionPolicySDKType)?.threshold ??
'0',
Expand Down Expand Up @@ -451,8 +467,13 @@ function GroupRow({
setActiveInfoModalId: (id: string | null) => void;
}) {
const policyAddress = (group.policies && group.policies[0]?.address) || '';
const groupName = group.ipfsMetadata?.title || 'Untitled Group';

let groupName = 'Untitled Group';
try {
const metadata = group.metadata ? JSON.parse(group.metadata) : null;
groupName = metadata?.title || 'Untitled Group';
} catch (e) {
console.warn('Failed to parse group metadata:', e);
}
const filterActiveProposals = (proposals: ProposalSDKType[]) => {
return proposals?.filter(
proposal =>
Expand Down
10 changes: 1 addition & 9 deletions components/groups/forms/groups/ConfirmationForm.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
import { useEffect, useState } from 'react';
import { TruncatedAddressWithCopy } from '@/components/react/addressCopy';
import { FormData } from '@/helpers/formReducer';
import { useFeeEstimation } from '@/hooks/useFeeEstimation';
import { uploadJsonToIPFS } from '@/hooks/useIpfs';
import { useTx } from '@/hooks/useTx';
import { cosmos } from '@liftedinit/manifestjs';
import { ThresholdDecisionPolicy } from '@liftedinit/manifestjs/dist/codegen/cosmos/group/v1/types';
Expand Down Expand Up @@ -35,11 +33,6 @@ export default function ConfirmationForm({
const { tx, isSigning, setIsSigning } = useTx('manifest');
const { estimateFee } = useFeeEstimation('manifest');

const uploadMetaDataToIPFS = async () => {
const CID = await uploadJsonToIPFS(jsonString);
return CID;
};

const minExecutionPeriod: Duration = {
seconds: BigInt(0),
nanos: 0,
Expand All @@ -62,7 +55,6 @@ export default function ConfirmationForm({
const handleConfirm = async () => {
setIsSigning(true);
try {
const CID = await uploadMetaDataToIPFS();
const msg = createGroupWithPolicy({
admin: address ?? '',
members: formData.members.map(member => ({
Expand All @@ -71,7 +63,7 @@ export default function ConfirmationForm({
metadata: member.name,
added_at: new Date(),
})),
groupMetadata: CID,
groupMetadata: jsonString,
groupPolicyMetadata: '',
groupPolicyAsAdmin: true,
decisionPolicy: {
Expand Down
96 changes: 54 additions & 42 deletions components/groups/forms/groups/GroupDetailsForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -10,51 +10,63 @@ import { isValidManifestAddress } from '@/utils/string';
import { MdContacts } from 'react-icons/md';
import { TailwindModal } from '@/components/react/modal';

const GroupSchema = Yup.object().shape({
title: Yup.string()
.required('Title is required')
.max(50, 'Title must not exceed 50 characters')
.noProfanity(),
authors: Yup.lazy(val =>
Array.isArray(val)
? Yup.array()
.of(
Yup.string().test(
'author-validation',
'Invalid author name or address',
function (value) {
if (value?.startsWith('manifest')) {
return isValidManifestAddress(value);
const GroupSchema = Yup.object()
.shape({
title: Yup.string()
.required('Title is required')
.max(50, 'Title must not exceed 50 characters')
.noProfanity(),
authors: Yup.lazy(val =>
Array.isArray(val)
? Yup.array()
.of(
Yup.string().test(
'author-validation',
'Invalid author name or address',
function (value) {
if (value?.startsWith('manifest')) {
return isValidManifestAddress(value);
}
return Yup.string()
.max(50, 'Author name must not exceed 50 characters')
.noProfanity('Profanity is not allowed')
.isValidSync(value);
}
return Yup.string()
.max(50, 'Author name must not exceed 50 characters')
.noProfanity('Profanity is not allowed')
.isValidSync(value);
}
)
)
)
.min(1, 'At least one author is required')
: Yup.string().test(
'single-author-validation',
'Invalid author name or address',
function (value) {
if (value?.startsWith('manifest')) {
return isValidManifestAddress(value);
.min(1, 'At least one author is required')
: Yup.string().test(
'single-author-validation',
'Invalid author name or address',
function (value) {
if (value?.startsWith('manifest')) {
return isValidManifestAddress(value);
}
return Yup.string()
.max(50, 'Author name must not exceed 50 characters')
.noProfanity('Profanity is not allowed')
.isValidSync(value);
}
return Yup.string()
.max(50, 'Author name must not exceed 50 characters')
.noProfanity('Profanity is not allowed')
.isValidSync(value);
}
)
),

description: Yup.string()
.required('Description is required')
.min(20, 'Description must be at least 20 characters')
.max(1000, 'Description must not exceed 1000 characters')
.noProfanity('Profanity is not allowed'),
});
)
),
description: Yup.string()
.required('Description is required')
.min(20, 'Description must be at least 20 characters')
.max(100, 'Description must not exceed 100 characters')
.noProfanity('Profanity is not allowed'),
})
.test(
'metadata-total-length',
'Total metadata length must not exceed 10000 characters',
function (values) {
const metadata = JSON.stringify({
title: values.title || '',
authors: Array.isArray(values.authors) ? values.authors.join(', ') : values.authors || '',
details: values.description || '',
});
return metadata.length <= 10000;
}
);

export default function GroupDetails({
nextStep,
Expand Down
1 change: 1 addition & 0 deletions components/groups/forms/groups/MemberInfoForm.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -247,6 +247,7 @@ export default function MemberInfoForm({
isOpen={isContactsOpen}
setOpen={setIsContactsOpen}
showContacts={true}
currentAddress={address}
onSelect={(selectedAddress: string) => {
if (activeMemberIndex !== null) {
setFieldValue(`members.${activeMemberIndex}.address`, selectedAddress);
Expand Down
64 changes: 37 additions & 27 deletions components/groups/modals/groupDetailsModal.tsx
Original file line number Diff line number Diff line change
@@ -1,15 +1,17 @@
import { TruncatedAddressWithCopy } from '@/components/react/addressCopy';
import { IPFSMetadata } from '@/hooks/useQueries';
import ProfileAvatar from '@/utils/identicon';
import {
GroupMemberSDKType,
GroupPolicyInfoSDKType,
ThresholdDecisionPolicySDKType,
} from '@liftedinit/manifestjs/dist/codegen/cosmos/group/v1/types';
import { PiXCircleLight } from 'react-icons/pi';

interface Group {
group: {
admin: string;
metadata: string;
ipfsMetadata: IPFSMetadata | null;
members: any[];
policies: any[];
members: GroupMemberSDKType[];
policies: GroupPolicyInfoSDKType[];
};
}

Expand All @@ -24,6 +26,19 @@ export function GroupDetailsModal({ group, modalId }: Group & { modalId: string
return adminAddresses.includes(address);
};

const metadata = (() => {
try {
return group.metadata ? JSON.parse(group.metadata) : null;
} catch (error) {
console.error('Failed to parse group metadata:', error);
return null;
}
})();

const authors = metadata?.authors || 'No authors available';
const summary = metadata?.summary || 'No summary available';
const details = metadata?.details || 'No details available';

return (
<dialog id={modalId} className="modal">
<div className="modal-box absolute max-w-4xl mx-auto rounded-lg md:ml-20 shadow-lg">
Expand All @@ -37,29 +52,19 @@ export function GroupDetailsModal({ group, modalId }: Group & { modalId: string
<div>
<p className="text-sm font-light mt-4 ">AUTHORS</p>
<div className="bg-base-200 shadow rounded-lg p-4 mt-2 mb-2">
<p className="text-md ">{group?.ipfsMetadata?.authors ?? 'No authors available'}</p>
<p className="text-md ">{authors}</p>
</div>
</div>
<div>
<p className="text-sm font-light mt-4 ">SUMMARY</p>
<div className="bg-base-200 shadow rounded-lg p-4 mt-2 mb-2">
<p className="text-md ">{group?.ipfsMetadata?.summary ?? 'No summary available'}</p>
<p className="text-md ">{summary}</p>
</div>
</div>
<div>
<p className="text-sm font-light mt-4 ">DETAILS</p>
<div className="bg-base-200 shadow rounded-lg p-4 mt-2 mb-2 max-h-[9.53rem] overflow-y-auto">
<p className="text-md text-wrap ">
{group?.ipfsMetadata?.details ?? 'No details available'}
</p>
</div>
</div>
<div>
<p className="text-sm font-light mt-4 ">FORUM</p>
<div className="bg-base-200 shadow rounded-lg p-4 mt-2 mb-2">
<p className="text-md ">
{group?.ipfsMetadata?.proposalForumURL ?? 'No forum URL available'}
</p>
<p className="text-md text-wrap ">{details}</p>
</div>
</div>
</div>
Expand All @@ -82,10 +87,14 @@ export function GroupDetailsModal({ group, modalId }: Group & { modalId: string
<p className="text-sm font-light mt-4 ">VOTING WINDOW</p>
<div className="bg-base-200 shadow rounded-lg p-4 mt-2 mb-2">
<p className="text-md ">
{policy?.decision_policy?.windows?.voting_period
{(policy?.decision_policy as ThresholdDecisionPolicySDKType)?.windows
?.voting_period
? Math.floor(
parseInt(policy.decision_policy.windows.voting_period.slice(0, -1)) /
86400
parseInt(
(
policy?.decision_policy as ThresholdDecisionPolicySDKType
)?.windows?.voting_period.seconds.toString() ?? '0'
) / 86400
)
: 'No voting period available'}{' '}
days
Expand All @@ -96,8 +105,9 @@ export function GroupDetailsModal({ group, modalId }: Group & { modalId: string
<p className="text-sm font-light mt-4 ">THRESHOLD</p>
<div className="bg-base-200 shadow rounded-lg p-4 mt-2 mb-2">
<p className="text-md ">
{policy?.decision_policy?.threshold ?? 'No threshold available'} /
{group?.members.length ?? 'No members available'}
{(policy?.decision_policy as ThresholdDecisionPolicySDKType)?.threshold ??
'No threshold available'}{' '}
/ {group?.members.length ?? 'No members available'}
</p>
</div>
</div>
Expand Down Expand Up @@ -152,12 +162,12 @@ export function GroupDetailsModal({ group, modalId }: Group & { modalId: string
/>
</td>
<td>
{isPolicyAdmin(member?.member?.address) &&
isAdmin(member?.member?.address) ? (
{isPolicyAdmin(member?.member?.address ?? '') &&
isAdmin(member?.member?.address ?? '') ? (
'Super Admin'
) : isPolicyAdmin(member?.member?.address) ? (
) : isPolicyAdmin(member?.member?.address ?? '') ? (
'Policy'
) : isAdmin(member?.member?.address) ? (
) : isAdmin(member?.member?.address ?? '') ? (
'Group'
) : (
<PiXCircleLight className="text-red-500 h-5 w-5" />
Expand Down
Loading

0 comments on commit 567ec47

Please sign in to comment.