diff --git a/.env.template b/.env.template index 6e738b40..6fc51e5f 100644 --- a/.env.template +++ b/.env.template @@ -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= diff --git a/.gitignore b/.gitignore index 45694eed..d6631a8b 100644 --- a/.gitignore +++ b/.gitignore @@ -35,6 +35,7 @@ apps/discord-bot/tsconfig.tsbuildinfo apps/indexer/tsconfig.tsbuildinfo prisma/dev.db .env +.env.* packages/composedb/.ceramic .idea/ diff --git a/apps/discord-bot/src/bots/discord/comments/handler.ts b/apps/discord-bot/src/bots/discord/comments/handler.ts index 53dc3f8f..24b95e34 100644 --- a/apps/discord-bot/src/bots/discord/comments/handler.ts +++ b/apps/discord-bot/src/bots/discord/comments/handler.ts @@ -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"; @@ -62,6 +62,8 @@ export const handleNewComment = async (clients: Clients, message: Message 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); } }; diff --git a/apps/discord-bot/src/bots/discord/threads/handler.ts b/apps/discord-bot/src/bots/discord/threads/handler.ts index 21c007b8..2b085d04 100644 --- a/apps/discord-bot/src/bots/discord/threads/handler.ts +++ b/apps/discord-bot/src/bots/discord/threads/handler.ts @@ -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"; @@ -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); } }; diff --git a/apps/discord-bot/src/bots/discord/utils.ts b/apps/discord-bot/src/bots/discord/utils.ts index 00c1172d..a99cd00b 100644 --- a/apps/discord-bot/src/bots/discord/utils.ts +++ b/apps/discord-bot/src/bots/discord/utils.ts @@ -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 => { return { @@ -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)); + }); + }); +} diff --git a/apps/discord-bot/src/config/config.ts b/apps/discord-bot/src/config/config.ts index bcac6120..c6a9f476 100644 --- a/apps/discord-bot/src/config/config.ts +++ b/apps/discord-bot/src/config/config.ts @@ -1,4 +1,5 @@ import {DIDSession} from "did-session"; +import {getBoolean} from "../core/utils/data"; export const config = { server: { @@ -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", }; diff --git a/apps/discord-bot/src/config/constants.ts b/apps/discord-bot/src/config/constants.ts index 591d1a56..a68acdca 100644 --- a/apps/discord-bot/src/config/constants.ts +++ b/apps/discord-bot/src/config/constants.ts @@ -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!", }, } diff --git a/apps/discord-bot/src/core/utils/data.ts b/apps/discord-bot/src/core/utils/data.ts index 587671ac..08d413b9 100644 --- a/apps/discord-bot/src/core/utils/data.ts +++ b/apps/discord-bot/src/core/utils/data.ts @@ -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; +} diff --git a/apps/discord-bot/tests/unit/utils/data.spec.ts b/apps/discord-bot/tests/unit/utils/data.spec.ts index 9c376ecd..55b835f2 100644 --- a/apps/discord-bot/tests/unit/utils/data.spec.ts +++ b/apps/discord-bot/tests/unit/utils/data.spec.ts @@ -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[] = [ @@ -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); + }); }); diff --git a/apps/web/public/devnode.png b/apps/web/public/devnode.png index 3b45c470..0b756218 100644 Binary files a/apps/web/public/devnode.png and b/apps/web/public/devnode.png differ diff --git a/apps/web/src/components/AvatarCard/AvatarCard.tsx b/apps/web/src/components/AvatarCard/AvatarCard.tsx index cb791808..f1ba22a4 100644 --- a/apps/web/src/components/AvatarCard/AvatarCard.tsx +++ b/apps/web/src/components/AvatarCard/AvatarCard.tsx @@ -19,8 +19,9 @@ export const AvatarCard = (props: AvatarCardProps) => { {`${props.name} {props.name &&
{props.name}
} diff --git a/apps/web/src/components/AvatarCard/types.ts b/apps/web/src/components/AvatarCard/types.ts index 1fe99a9f..9dcd4349 100644 --- a/apps/web/src/components/AvatarCard/types.ts +++ b/apps/web/src/components/AvatarCard/types.ts @@ -4,6 +4,7 @@ export interface AvatarCardProps { name?: string; address?: string; classes?: string; + imageClasses?: string; onAddressClick?(address: string): void; onClick?(): void; } diff --git a/apps/web/src/components/Comment/Comment.tsx b/apps/web/src/components/Comment/Comment.tsx index 37e3a5d1..12fcd164 100644 --- a/apps/web/src/components/Comment/Comment.tsx +++ b/apps/web/src/components/Comment/Comment.tsx @@ -1,6 +1,6 @@ import {FlexColumn, FlexRow} from "../Flex"; -import Image from "next/image"; import {showUserProfile, useAppDispatch} from "../../store"; +import {AvatarCard} from "../AvatarCard"; import {DownVote, Spinner, UpVote} from "../Icons"; import {useState} from "react"; import * as utils from "../../utils"; @@ -41,12 +41,10 @@ export const Comment = (props: CommentProps) => { dispatch(showUserProfile({userProfileId: userId})); }} > - {`${user?.platformUsername} diff --git a/apps/web/src/components/CommunityAvatar/CommunityAvatar.tsx b/apps/web/src/components/CommunityAvatar/CommunityAvatar.tsx index 5b7bdfd6..cb6557e5 100644 --- a/apps/web/src/components/CommunityAvatar/CommunityAvatar.tsx +++ b/apps/web/src/components/CommunityAvatar/CommunityAvatar.tsx @@ -13,7 +13,7 @@ export const CommunityAvatar = (props: CommunityAvatarProps) => {
{ >
{

diff --git a/apps/web/src/components/Search/Search.tsx b/apps/web/src/components/Search/Search.tsx index 4b68c227..351d17c1 100644 --- a/apps/web/src/components/Search/Search.tsx +++ b/apps/web/src/components/Search/Search.tsx @@ -2,7 +2,7 @@ import {SearchProps} from "./types"; export const Search = (props: SearchProps) => { return ( -
+
diff --git a/apps/web/src/components/Thread/Thread.tsx b/apps/web/src/components/Thread/Thread.tsx index 83fe50ed..15db4985 100644 --- a/apps/web/src/components/Thread/Thread.tsx +++ b/apps/web/src/components/Thread/Thread.tsx @@ -1,7 +1,7 @@ import {ThreadProps} from "./type"; import {FlexColumn, FlexRow} from "../Flex"; -import Image from "next/image"; import {showUserProfile, useAppDispatch} from "../../store"; +import {AvatarCard} from "../AvatarCard"; import {Markdown} from "../Markdown"; export const Thread = ({thread}: ThreadProps) => { @@ -17,12 +17,10 @@ export const Thread = ({thread}: ThreadProps) => { onClick={() => { dispatch(showUserProfile({userProfileId: userId})); }}> - {`${user?.platformUsername}
diff --git a/apps/web/src/components/UserAccount/UserAccount.tsx b/apps/web/src/components/UserAccount/UserAccount.tsx index 9a806a5a..710013b7 100644 --- a/apps/web/src/components/UserAccount/UserAccount.tsx +++ b/apps/web/src/components/UserAccount/UserAccount.tsx @@ -29,16 +29,16 @@ const UserAccount = (props) => { >
-
-
+
+
Disconnect
logout
-
View Profile
diff --git a/apps/web/src/pages/community.tsx b/apps/web/src/pages/community.tsx index 5ee42cf4..de7c9692 100644 --- a/apps/web/src/pages/community.tsx +++ b/apps/web/src/pages/community.tsx @@ -84,15 +84,17 @@ const CommunityPage = () => { } return ( -
+
-
-
+
+
{communityName && (

{communityName}

)} - {}} /> +
+ {}} /> +
-
+
{data?.pages?.map((page) => ( page?.edges?.map((thread) => ( { } return ( -
-
+
+
+

your feed

{}}/> -
+
{threads && threads.map((thread) => ( { /> )}
+
); }; diff --git a/apps/web/src/pages/index.tsx b/apps/web/src/pages/index.tsx index 3d284782..aa5f0752 100644 --- a/apps/web/src/pages/index.tsx +++ b/apps/web/src/pages/index.tsx @@ -42,7 +42,7 @@ const Home: NextPage = () => {
{data?.pages?.map((page) => { return ( - page?.edges?.map((community, index) => { + page?.edges?.map((community) => { if (isNil(community.node)) return <>; if (isEmpty(community.node?.socialPlatforms.edges)) return <>; let tags: any; @@ -55,14 +55,13 @@ const Home: NextPage = () => { return ( { } return ( -
+
{currentThread.data?.node && }
@@ -145,8 +145,8 @@ export const ThreadSection = (props: ThreadSectionProps) => { />
-
-
+
+