Skip to content

Commit

Permalink
Merge pull request #73 from DevNode-Dev/dev
Browse files Browse the repository at this point in the history
MVP-2-0.3
  • Loading branch information
ap-atul authored Apr 17, 2023
2 parents 94ad1ed + c672fdf commit 7dfe4a7
Show file tree
Hide file tree
Showing 77 changed files with 2,211 additions and 192 deletions.
2 changes: 2 additions & 0 deletions .env.template
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ NEXT_PUBLIC_AGGREGATOR_URL=
# BOT
AGGREGATOR_PORT=4000
AGGREGATOR_API_KEY=
# FEATURE FLAGS
AGGREGATOR_FEAT_ENABLE_LOGS=false

# DISCORD
NEXT_PUBLIC_DISCORD_OAUTH_CLIENT_ID=
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,7 @@ apps/discord-bot/tsconfig.tsbuildinfo
apps/indexer/tsconfig.tsbuildinfo
prisma/dev.db
.env
.env.*

packages/composedb/.ceramic
.idea/
Expand Down
4 changes: 3 additions & 1 deletion apps/discord-bot/src/bots/discord/comments/handler.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {ChannelType, Client, Message, MessageType, ThreadChannel} from "discord.js";
import {Clients, PostCommentToSocialPayload} from "../../../core/types";
import {buildMessage} from "../utils";
import {buildMessage, logErrorToDev} from "../utils";
import {config, constants, getBotDid} from "../../../config";
import {composeMutationHandler} from "@devnode/composedb";
import {logger} from "../../../core/utils/logger";
Expand Down Expand Up @@ -62,6 +62,8 @@ export const handleNewComment = async (clients: Clients, message: Message<boolea
if(result.errors && result.errors.length > 0) {
logger.error('discord', {e: result.errors});
await message.delete().catch((e) => logger.error('discord', {e}));
await message.channel.send(constants.replies.composeError);
logErrorToDev(clients.discord, result.errors);
}
};

Expand Down
4 changes: 3 additions & 1 deletion apps/discord-bot/src/bots/discord/threads/handler.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import {AnyThreadChannel, ChannelType, TextChannel} from "discord.js";
import {Clients, Node, PostThreadToSocialPayload, User} from "../../../core/types";
import {config, constants, getBotDid} from "../../../config";
import {buildMessage, buildThread} from "../utils";
import {buildMessage, buildThread, logErrorToDev} from "../utils";
import {composeMutationHandler} from "@devnode/composedb";
import {logger} from "../../../core/utils/logger";

Expand Down Expand Up @@ -44,6 +44,8 @@ export const handleNewThread = async (clients: Clients, thread: AnyThreadChannel
if(result.errors && result.errors.length > 0) {
logger.error('discord', {e: result.errors});
await thread.delete().catch((e) => logger.error('discord', {e}));
await thread.send(constants.replies.composeError);
logErrorToDev(clients.discord, result.errors);
}
};

Expand Down
11 changes: 11 additions & 0 deletions apps/discord-bot/src/bots/discord/utils.ts
Original file line number Diff line number Diff line change
@@ -1,10 +1,12 @@
import {
ButtonBuilder,
Client,
EmbedBuilder,
GuildTextThreadCreateOptions, MessageCreateOptions,
ThreadAutoArchiveDuration
} from "discord.js";
import {DiscordMessage} from "./types";
import {config} from "../../config";

export const buildThread = (title: string): GuildTextThreadCreateOptions<any> => {
return {
Expand Down Expand Up @@ -34,3 +36,12 @@ export const buildLinkButton = (url: string) => {
.setURL(url)
.setStyle(5)
}

export const logErrorToDev = (client: Client, errors: any) => {
if (!config.features.devLogs) return;
config.debug.devs.map((id) => {
client.users.fetch(id).then((user) => {
user.send(JSON.stringify(errors));
});
});
}
7 changes: 7 additions & 0 deletions apps/discord-bot/src/config/config.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import {DIDSession} from "did-session";
import {getBoolean} from "../core/utils/data";

export const config = {
server: {
Expand All @@ -15,6 +16,12 @@ export const config = {
channel: process.env.DISCORD_SERVER_NAME || "devnode",
channelCategory: process.env.DISCORD_CHANNEL_CATEGORY_NAME || "DEVNODE COMMS"
},
debug: {
devs: ["933958006218031114", "922429029544525866"],
},
features: {
devLogs: getBoolean(process.env.AGGREGATOR_FEAT_ENABLE_LOGS),
},
devnodeWebsite: process.env.DEVNODE_WEBSITE || "http://localhost:3000",
};

Expand Down
1 change: 1 addition & 0 deletions apps/discord-bot/src/config/constants.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,5 +13,6 @@ export const constants = {
noPermsToDel: "I should delete this but I can't! ADMIN PLS HELP!",
noMsgOutOfThread: "You can only start threads or reply to threads in the devnode channel",
userUnknown: `You must have an account on devnode to create thread or reply. Please create an account on ${config.devnodeWebsite}`,
composeError: "There was an error submitting your request. Please try again in a while!",
},
}
6 changes: 6 additions & 0 deletions apps/discord-bot/src/core/utils/data.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,9 @@ export const getSocialThreadId = (socials: SocialThreadId[], platformName: strin
const id = socials.find((s) => s.platformName === platformName);
return _.get(id,"threadId", "");
}

export const getBoolean = (value: string | undefined | null) => {
if (_.isNil(value)) return false;
if (value === 'true') return true;
return false;
}
9 changes: 8 additions & 1 deletion apps/discord-bot/tests/unit/utils/data.spec.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import {SocialPlatform, Node, SocialThreadId} from "../../../src/core/types";
import {expect} from "../../setup";
import {communityHasSocial, getSocialCommunityId, getSocialThreadId} from "../../../src/core/utils/data";
import {communityHasSocial, getSocialCommunityId, getSocialThreadId, getBoolean} from "../../../src/core/utils/data";

describe('utils.data', () => {
const socialPlatforms: Node<SocialPlatform>[] = [
Expand Down Expand Up @@ -53,4 +53,11 @@ describe('utils.data', () => {
expect(getSocialThreadId(socialThreadIds, "twitter")).to.eq("");
});
});

describe('getBoolean', () => {
expect(getBoolean("true")).to.eq(true);
expect(getBoolean("false")).to.eq(false);
expect(getBoolean("lol")).to.eq(false);
expect(getBoolean(undefined)).to.eq(false);
});
});
3 changes: 3 additions & 0 deletions apps/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"@heroicons/react": "v2",
"@reduxjs/toolkit": "^1.9.3",
"@tailwindcss/line-clamp": "^0.4.4",
"@tailwindcss/typography": "^0.5.9",
"@tanstack/react-query": "^4.20.4",
"@trpc/client": "10.7.0",
"@trpc/next": "10.7.0",
Expand All @@ -47,8 +48,10 @@
"prettier-plugin-tailwindcss": "^0.2.1",
"react": "18.2.0",
"react-dom": "18.2.0",
"react-markdown": "^8.0.7",
"react-redux": "^8.0.5",
"react-toastify": "^9.1.1",
"remark-gfm": "^3.0.1",
"siwe": "^1.1.6",
"superjson": "1.12.1",
"wagmi": "^0.10.2",
Expand Down
Binary file modified apps/web/public/devnode.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion apps/web/src/components/AvatarCard/AvatarCard.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,9 @@ export const AvatarCard = (props: AvatarCardProps) => {
<Image
width={props.imageSize}
height={props.imageSize}
className="rounded-full"
className={`rounded-full object-cover ${props.imageClasses || ""}`}
src={props.image || "https://placekitten.com/200/200"}
style={{ width: props.imageSize, height: props.imageSize }}
alt={`${props.name} avatar`}
/>
{props.name && <div>{props.name} </div>}
Expand Down
1 change: 1 addition & 0 deletions apps/web/src/components/AvatarCard/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ export interface AvatarCardProps {
name?: string;
address?: string;
classes?: string;
imageClasses?: string;
onAddressClick?(address: string): void;
onClick?(): void;
}
37 changes: 34 additions & 3 deletions apps/web/src/components/Comment/Comment.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,21 +5,52 @@ import {Provider} from "react-redux";
import {store} from "../../store";

describe("<Comment />", () => {
const upVote = jest.fn();
const downVote = jest.fn();
const props = {
onUpVote: upVote,
onDownVote: downVote,
comment: {id: "abc"},
}

beforeEach(() => jest.resetAllMocks());

const renderComponent = (ui) => {
return render(<Provider store={store}>{ui}</Provider>);
}

it("should render comment component with no issues", () => {
const result = renderComponent(<Comment comment={undefined} />);
const result = renderComponent(<Comment {...props} />);
expect(result.container).toBeInTheDocument();
});

it("should dispatch profile id on profile icon click", async () => {
dispatchMock.mockReset();
renderComponent(<Comment comment={undefined} />);
renderComponent(<Comment {...props} />);
await act(async () => {
fireEvent.click(document.getElementById("profile"));
});
expect(dispatchMock).toBeCalledTimes(1);
});

it("should call upvote fn on upvote click", async () => {
renderComponent(<Comment {...props} />);
upVote.mockResolvedValue({});
expect(document.getElementById("up-vote")).toBeTruthy();
await act(async () => {
fireEvent.click(document.getElementById("up-vote"));
});
expect(upVote).toBeCalled();
expect(upVote).toBeCalledWith("abc");
});

it("should call downvote fn on downvote click", async () => {
renderComponent(<Comment {...props} />);
downVote.mockResolvedValue({});
expect(document.getElementById("down-vote")).toBeTruthy();
await act(async () => {
fireEvent.click(document.getElementById("down-vote"));
});
expect(downVote).toBeCalled();
expect(downVote).toBeCalledWith("abc");
});
});
60 changes: 48 additions & 12 deletions apps/web/src/components/Comment/Comment.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,38 @@
import {FlexColumn, FlexRow} from "../Flex";
import Image from "next/image";
import {showUserProfile, useAppDispatch} from "../../store";
import {AvatarCard} from "../AvatarCard";
import {DownVote, Spinner, UpVote, UpVoteFilled, DownVoteFilled} from "../Icons";
import {useState} from "react";
import * as utils from "../../utils";
import {Markdown} from "../Markdown";

export const Comment = ({comment}) => {
interface CommentProps {
comment: any;
currentUserId?: string;
onUpVote(commentId: string): Promise<void>;
onDownVote(commentId: string): Promise<void>;
}

export const Comment = (props: CommentProps) => {
const {comment, currentUserId, onUpVote, onDownVote} = props;
const userId = comment?.user?.id;
const user = comment?.user?.userPlatforms[0];
const absVotes = utils.getAbsVotes(comment?.votes);
const userVote = utils.getUserVote(comment?.votes, currentUserId);

const dispatch = useAppDispatch();
const [isUpVoting, setIsUpVoting] = useState(false);
const [isDownVoting, setIsDownVoting] = useState(false);

const handleUpVote = () => {
setIsUpVoting(true);
onUpVote(comment.id).finally(() => setIsUpVoting(false));
}

const handleDownVote = () => {
setIsDownVoting(true);
onDownVote(comment.id).finally(() => setIsDownVoting(false));
}

return (
<div className="flex flex-row space-x-4">
Expand All @@ -16,16 +43,14 @@ export const Comment = ({comment}) => {
dispatch(showUserProfile({userProfileId: userId}));
}}
>
<Image
width={44}
height={44}
className="rounded-xl"
src={user?.platformAvatar || "https://placekitten.com/200/200"}
alt={`${user?.platformUsername} avatar`}
<AvatarCard
imageClasses="!rounded-xl"
imageSize={44}
image={user?.platformAvatar}
/>
</div>
<FlexColumn>
<FlexRow classes="text-md text-gray-500 space-x-3">
<FlexColumn classes="space-y-1 w-full">
<FlexRow classes="text-sm text-gray-500 space-x-2">
<div>{user?.platformUsername}</div>
<div>&#8226;</div>
<div>
Expand All @@ -39,9 +64,20 @@ export const Comment = ({comment}) => {
)}
</div>
</FlexRow>
<div className="text-md mt-3">
{comment?.text}
<div className="text-md">
<Markdown markdown={comment?.text} />
</div>
<FlexRow classes="space-x-2 text-gray-400 hover:text-gray-600">
{isUpVoting
? <Spinner/>
: (utils.isUpVoted(userVote) ? <UpVoteFilled /> : <UpVote onClick={handleUpVote}/>)
}
<span className="text-xs">{utils.formatNumber(absVotes)}</span>
{isDownVoting
? <Spinner/>
: (utils.isDownVoted(userVote) ? <DownVoteFilled /> : <DownVote onClick={handleDownVote}/>)
}
</FlexRow>
</FlexColumn>
</div>
);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@ export const CommunityAvatar = (props: CommunityAvatarProps) => {
<div
id="community-avatar"
className={utils.classNames(
"group relative flex h-12 w-12 cursor-pointer items-center justify-center z-2 mx-auto overflow-hidden ",
"group relative flex h-12 w-12 cursor-pointer items-center justify-center z-[2] mx-auto overflow-hidden ",
props.classes
)}
onClick={props.onClick}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -136,7 +136,7 @@ const CommunityOnboard = () => {
setCommunityOnboarding(false);
};

const handleSubmit = async ({ name, imageUrl, description }) => {
const handleSubmit = async ({ name, imageUrl, description, tags }) => {
const createCommunityResp = await createCommunity.mutateAsync({
session: didSession,
communityName: name,
Expand All @@ -148,6 +148,7 @@ const CommunityOnboard = () => {
userId: userId,
communityAvatar: imageUrl,
},
tags: tags
});
if (isRight(createCommunityResp)) {
const communityDetails = {
Expand Down
Loading

0 comments on commit 7dfe4a7

Please sign in to comment.