{
"data": {
"f2bc8abdb8ba64fe5aac9689ded9491ff0e6fdcd7a5c680b7cf364142d1789fb": {
"widget": {
"SayALot": {
"": "// SayALot\r\n\r\n//===============================================INITIALIZATION=====================================================\r\nlet { sharedBlockHeight, tagShared, isTest, accountId } = props;\r\nsharedBlockHeight = Number(sharedBlockHeight);\r\n\r\nconst sbtWhiteList = [\r\n \"fractal.i-am-human.near - class 1\",\r\n \"community.i-am-human.near - class 1\",\r\n \"community.i-am-human.near - class 2\",\r\n \"community.i-am-human.near - class 3\",\r\n \"public\",\r\n];\r\n\r\nconst initSbtsNames = [sbtWhiteList[0]];\r\n\r\nconst sbtsNames = state.sbt;\r\n\r\nconst initLibsCalls = {\r\n article: [\r\n {\r\n functionName: \"getArticles\",\r\n key: \"articles\",\r\n props: {\r\n env: isTest ? \"test\" : \"prod\",\r\n sbtsNames: sbtWhiteList,\r\n },\r\n },\r\n {\r\n functionName: \"canUserCreateArticle\",\r\n key: \"canLoggedUserCreateArticle\",\r\n props: {\r\n accountId: context.accountId,\r\n sbtsNames: sbtWhiteList,\r\n },\r\n },\r\n ],\r\n};\r\n\r\naccountId = context.accountId;\r\n\r\nconst tabs = {\r\n SHOW_ARTICLES_LIST: { id: 0 },\r\n SHOW_ARTICLE: { id: 1 },\r\n ARTICLE_WORKSHOP: { id: 2 },\r\n SHOW_ARTICLES_LIST_BY_AUTHORS: { id: 3 },\r\n};\r\n\r\nfunction getInitialFilter() {\r\n if (sharedBlockHeight) {\r\n return {\r\n parameterName: \"getPost\",\r\n parameterValue: sharedBlockHeight,\r\n };\r\n } else if (tagShared) {\r\n return {\r\n parameterName: \"tag\",\r\n parameterValue: tagShared,\r\n };\r\n } else if (authorShared) {\r\n return {\r\n parameterName: \"author\",\r\n parameterValue: authorShared,\r\n };\r\n } else {\r\n return {\r\n parameterName: \"\",\r\n };\r\n }\r\n}\r\n\r\nfunction getInitialTabId() {\r\n if (sharedBlockHeight) {\r\n return tabs.SHOW_ARTICLE.id;\r\n } else {\r\n return tabs.SHOW_ARTICLES_LIST.id;\r\n }\r\n}\r\n\r\nState.init({\r\n displayedTabId: getInitialTabId(),\r\n articleToRenderData: {},\r\n filterBy: getInitialFilter(),\r\n authorsProfiles: [],\r\n functionsToCallByLibrary: initLibsCalls,\r\n sbtsNames: initSbtsNames,\r\n sbts: initSbtsNames,\r\n firstRender: !isNaN(sharedBlockHeight),\r\n});\r\n\r\nlet newLibsCalls = state.functionsToCallByLibrary;\r\n\r\nState.update({ libsCalls: newLibsCalls });\r\n\r\n//=============================================END INITIALIZATION===================================================\r\n\r\n//==================================================CONSTS==========================================================\r\n\r\nconst authorForWidget = \"sayalot.near\";\r\n// const authorForWidget =\r\n// \"f2bc8abdb8ba64fe5aac9689ded9491ff0e6fdcd7a5c680b7cf364142d1789fb\";\r\n// const authorForWidget = \"kenrou-it.near\";\r\n// const authorForWidget = \"silkking.near\";\r\n\r\nconst thisWidgetName = \"SayALot\";\r\n\r\nconst widgets = {\r\n // sayALot: `${authorForWidget}/widget/${thisWidgetName}`,\r\n sayALot: `f2bc8abdb8ba64fe5aac9689ded9491ff0e6fdcd7a5c680b7cf364142d1789fb/widget/${thisWidgetName}`,\r\n // create: `${authorForWidget}/widget/SayALot.Create`,////////////////////////////////////////////////////////////////////////////////\r\n create: `f2bc8abdb8ba64fe5aac9689ded9491ff0e6fdcd7a5c680b7cf364142d1789fb/widget/SayALot.Create`, //////////////////////////////////////////////////////////////////////////////////\r\n header: `${authorForWidget}/widget/SayALot.NavBar`,\r\n showArticlesList: `${authorForWidget}/widget/SayALot.AllArticlesList`,\r\n showArticlesListSortedByAuthors: `${authorForWidget}/widget/SayALot.AllArticlesSortByAuthors`,\r\n articlesByAuthorCard: `${authorForWidget}/widget/SayALot.ArticlesByAuthorCard`,\r\n generalCard: `${authorForWidget}/widget/SayALot.GeneralCard`,\r\n // articleView: `${authorForWidget}/widget/SayALot.ArticleView`,////////////////////////////////////////////////////////////////////////\r\n articleView: `f2bc8abdb8ba64fe5aac9689ded9491ff0e6fdcd7a5c680b7cf364142d1789fb/widget/SayALot.ArticleView`, /////////////////////////////////////////////////////////////////////////\r\n reactions: `${authorForWidget}/widget/SayALot.Reactions`,\r\n addComment: `${authorForWidget}/widget/SayALot.AddComment`,\r\n commentView: `${authorForWidget}/widget/SayALot.CommentView`,\r\n libSBT: `${authorForWidget}/widget/lib.SBT`,\r\n libComment: `${authorForWidget}/widget/lib.comment`,\r\n libArticle: `${authorForWidget}/widget/lib.article`,\r\n libEmojis: `${authorForWidget}/widget/lib.emojis`,\r\n libUpVotes: `${authorForWidget}/widget/lib.upVotes`,\r\n upVoteButton: `${authorForWidget}/widget/SayALot.UpVoteButton`,\r\n styledComponents: \"rubycop.near/widget/NDC.StyledComponents\",\r\n newStyledComponents: {\r\n Element: {\r\n Badge: \"nearui.near/widget/Element.Badge\",\r\n User: \"nearui.near/widget/Element.User\",\r\n },\r\n Feedback: {\r\n Spinner: \"nearui.near/widget/Feedback.Spinner\",\r\n },\r\n Input: {\r\n Button: \"nearui.near/widget/Input.Button\",\r\n Checkbox: \"nearui.near/widget/Input.Checkbox\",\r\n Select: \"nearui.near/widget/Input.Select\",\r\n },\r\n },\r\n};\r\n\r\nconst libSrcArray = [widgets.libArticle];\r\n\r\nconst profile = props.profile ?? Social.getr(`${accountId}/profile`);\r\nif (profile === null) {\r\n return \"Loading\";\r\n}\r\n\r\nlet authorProfile = {};\r\nif (state.filterBy.parameterName == \"author\") {\r\n authorProfile = Social.getr(`${state.filterBy.parameterValue}/profile`);\r\n}\r\n\r\nconst brand = {\r\n homePageId: tabs.SHOW_ARTICLES_LIST.id,\r\n brandName: \"Say a lot\",\r\n logoHref:\r\n \"https://ipfs.near.social/ipfs/bafkreiaqxa4st4vp4rtq2iyobdgqe5tpfg55mmyvfg25upd2qplcxylyfi\",\r\n logoRemWidth: 6,\r\n logoRemHeight: 6,\r\n};\r\n\r\nconst navigationPills = [\r\n { id: tabs.SHOW_ARTICLES_LIST.id, title: \"Articles\" },\r\n { id: tabs.SHOW_ARTICLES_LIST_BY_AUTHORS.id, title: \"Authors\" },\r\n];\r\n\r\nconst navigationButtons = [\r\n // { id: tabs.ARTICLE_WORKSHOP.id, title: \"+Create article\" },\r\n];\r\n\r\nconst sbts = state.sbts;\r\n\r\nconst initialBodyAtCreation = state.editArticleData.body;\r\nconst canLoggedUserCreateArticle = state.canLoggedUserCreateArticle[sbts[0]];\r\n\r\n//=================================================END CONSTS=======================================================\r\n\r\n//=================================================GET DATA=========================================================\r\nconst finalArticles = state.articles;\r\n\r\nfunction getArticlesToRender() {\r\n if (sharedBlockHeight && finalArticles && state.firstRender) {\r\n let finalArticlesSbts = Object.keys(finalArticles);\r\n let allArticles = [];\r\n\r\n finalArticlesSbts.forEach((sbt) => {\r\n allArticles = [...allArticles, ...finalArticles[sbt]];\r\n });\r\n\r\n return allArticles;\r\n } else {\r\n return finalArticles[sbts[0]];\r\n }\r\n}\r\n\r\nconst articlesToRender = getArticlesToRender() ?? [];\r\n\r\nfunction filterArticlesByTag(tag, articles) {\r\n return articles.filter((article) => {\r\n return article.tags.includes(tag);\r\n });\r\n}\r\n\r\nfunction filterArticlesByAuthor(author, articles) {\r\n return articles.filter((article) => {\r\n return article.author === author;\r\n });\r\n}\r\n\r\nfunction filterOnePost(blockHeight, articles) {\r\n if (articles) {\r\n return articles.filter((article) => article.blockHeight === blockHeight);\r\n } else {\r\n return [];\r\n }\r\n}\r\n\r\nif (state.filterBy.parameterName === \"tag\") {\r\n articlesToRender = filterArticlesByTag(\r\n state.filterBy.parameterValue,\r\n articlesToRender\r\n );\r\n} else if (state.filterBy.parameterName === \"author\") {\r\n articlesToRender = filterArticlesByAuthor(\r\n state.filterBy.parameterValue,\r\n articlesToRender\r\n );\r\n} else if (state.filterBy.parameterName === \"getPost\") {\r\n articlesToRender = filterOnePost(\r\n state.filterBy.parameterValue,\r\n articlesToRender\r\n );\r\n\r\n if (articlesToRender.length > 0) {\r\n State.update({ articleToRenderData: articlesToRender[0] });\r\n }\r\n}\r\n//===============================================END GET DATA=======================================================\r\n\r\n//=============================================STYLED COMPONENTS====================================================\r\nconst CallLibrary = styled.div`\r\n display: block;\r\n`;\r\n\r\nconst ShareInteractionGeneralContainer = styled.div`\r\n position: fixed;\r\n display: flex;\r\n justify-content: center;\r\n align-items: center;\r\n top: 0;\r\n left: 0;\r\n height: 100vh;\r\n width: 100vw;\r\n backdrop-filter: blur(10px);\r\n z-index: 1;\r\n`;\r\n\r\nconst ShareInteractionMainContainer = styled.div`\r\n display: flex;\r\n flex-direction: column;\r\n background: white;\r\n padding: 1rem;\r\n border-radious: 12px;\r\n`;\r\n\r\nconst ClosePopUpContainer = styled.div`\r\n display: flex; \r\n flex-direction: row-reverse;\r\n`;\r\n\r\nconst CloseIcon = styled.div`\r\n cursor: pointer;\r\n`;\r\n\r\nconst PopUpDescription = styled.p`\r\n color: #474D55;\r\n`;\r\n\r\nconst ShowLinkShared = styled.div`\r\n display: flex;\r\n justify-content: space-between;\r\n align-items: center;\r\n background-color: #F2F6FA;\r\n padding: 1rem 2rem;\r\n border-radius: 17px;\r\n`;\r\n\r\nconst LinkShared = styled.span`\r\n color: #0065FF;\r\n word-wrap: anywhere;\r\n`;\r\n\r\nconst ClipboardContainer = styled.div`\r\n display: flex;\r\n flex-direction: column;\r\n align-items: center;\r\n margin-left: 0.5rem;\r\n min-width: 2.5rem;\r\n`;\r\n\r\nconst ClipboardIcon = styled.i`\r\n color: ${state.linkCopied ? \"#0065FF\" : \"black\"};\r\n transition: color 0.3s linear;\r\n cursor: pointer;\r\n`;\r\n\r\nconst CopiedFeedback = styled.span`\r\n font-size: 0.7rem;\r\n color: #6c757d;\r\n`;\r\n\r\nconst SmallButton = styled.button`\r\nposition: relative;\r\n border: 0;\r\n background: transparent;\r\n width: 35px;\r\n height: 35px;\r\n`;\r\n//===========================================END STYLED COMPONENTS==================================================\r\n\r\n//================================================COMPONENTS========================================================\r\nconst renderShareInteraction = () => {\r\n return (\r\n <ShareInteractionGeneralContainer>\r\n <ShareInteractionMainContainer>\r\n <ClosePopUpContainer>\r\n <CloseIcon\r\n className=\"bi bi-x\"\r\n onClick={() =>\r\n State.update({ showShareModal: false, linkCopied: false })\r\n }\r\n ></CloseIcon>\r\n </ClosePopUpContainer>\r\n <h3>Share</h3>\r\n <PopUpDescription>Use this link to share the article</PopUpDescription>\r\n <ShowLinkShared>\r\n <LinkShared>{getLink()}</LinkShared>\r\n <ClipboardContainer>\r\n <ClipboardIcon\r\n className=\"bi-clipboard\"\r\n onClick={() => {\r\n clipboard.writeText(getLink());\r\n State.update({ linkCopied: true });\r\n }}\r\n ></ClipboardIcon>\r\n {state.linkCopied && <CopiedFeedback>Copied!</CopiedFeedback>}\r\n </ClipboardContainer>\r\n </ShowLinkShared>\r\n </ShareInteractionMainContainer>\r\n </ShareInteractionGeneralContainer>\r\n );\r\n};\r\n\r\nconst renderSelectorLabel = () => {\r\n return (\r\n <>\r\n <span>Post & Filter Topics by SBT</span>\r\n\r\n <SmallButton>\r\n <OverlayTrigger\r\n placement=\"top\"\r\n overlay={\r\n <Tooltip>\r\n <p className=\"m-0\">Topics for Community SBT Holders.</p>\r\n <p className=\"m-0\">Anyone can post to Public.</p>\r\n </Tooltip>\r\n }\r\n >\r\n <i className=\"bi bi-info-circle\"></i>\r\n </OverlayTrigger>\r\n </SmallButton>\r\n </>\r\n );\r\n};\r\n//==============================================END COMPONENTS======================================================\r\n\r\n//=================================================FUNCTIONS========================================================\r\n\r\nfunction getValidEditArticleDataTags() {\r\n let tags = state.editArticleData.tags;\r\n let newFormatTags = {};\r\n\r\n tags &&\r\n tags.map((tag) => {\r\n newFormatTags[tag] = \"\";\r\n });\r\n return newFormatTags;\r\n}\r\n\r\nfunction createSbtOptions() {\r\n return sbtWhiteList.map((option, i) => {\r\n const title = \"\";\r\n\r\n if (option === \"fractal.i-am-human.near - class 1\") {\r\n title = \"General\";\r\n } else if (option === \"community.i-am-human.near - class 1\") {\r\n title = \"OG\";\r\n } else if (option === \"community.i-am-human.near - class 2\") {\r\n title = \"Contributor\";\r\n } else if (option === \"community.i-am-human.near - class 3\") {\r\n title = \"Core Contributor\";\r\n } else {\r\n title = \"Public\";\r\n }\r\n\r\n if (i == 0) {\r\n //The first options is always the default one\r\n return { title, default: true, value: option };\r\n } else {\r\n return { title, value: option };\r\n }\r\n });\r\n}\r\n\r\nconst initialCreateState = {\r\n title: state.editArticleData.title ?? \"\",\r\n articleBody: state.editArticleData.body ?? initialBodyAtCreation,\r\n tags: state.editArticleData.tags ? getValidEditArticleDataTags() : {},\r\n libsCalls: { comment: {}, article: {}, emojis: {}, upVotes: {} },\r\n sbts: [sbtWhiteList[0]],\r\n};\r\n\r\nfunction stateUpdate(obj) {\r\n State.update(obj);\r\n}\r\n\r\nfunction handleOpenArticle(articleToRenderData) {\r\n State.update({\r\n displayedTabId: tabs.SHOW_ARTICLE.id,\r\n articleToRenderData,\r\n editArticleData: undefined,\r\n });\r\n}\r\n\r\nfunction handleEditArticle(articleData) {\r\n State.update({\r\n displayedTabId: tabs.ARTICLE_WORKSHOP.id,\r\n editArticleData: articleData,\r\n });\r\n}\r\n\r\nfunction handleFilterArticles(filter) {\r\n State.update({\r\n filterBy: {\r\n parameterName: filter.filterBy,\r\n parameterValue: filter.value,\r\n },\r\n displayedTabId: tabs.SHOW_ARTICLES_LIST.id,\r\n editArticleData: undefined,\r\n });\r\n}\r\n\r\nfunction handleBackButton() {\r\n props.editArticleData\r\n ? State.update({\r\n displayedTabId: tabs.SHOW_ARTICLE.id,\r\n editArticleData: undefined,\r\n firstRender: false,\r\n filterBy: {\r\n parameterName: \"\",\r\n parameterValue: undefined,\r\n handleBackClicked: true,\r\n },\r\n })\r\n : State.update({\r\n displayedTabId: tabs.SHOW_ARTICLES_LIST.id,\r\n articleToRenderData: {},\r\n editArticleData: undefined,\r\n firstRender: false,\r\n filterBy: {\r\n parameterName: \"\",\r\n parameterValue: undefined,\r\n handleBackClicked: true,\r\n },\r\n });\r\n}\r\n\r\nfunction handleGoHomeButton() {\r\n State.update({\r\n displayedTabId: tabs.SHOW_ARTICLES_LIST.id,\r\n articleToRenderData: {},\r\n filterBy: { parameterName: \"\", parameterValue: {} },\r\n editArticleData: undefined,\r\n });\r\n}\r\n\r\nfunction handlePillNavigation(navegateTo) {\r\n State.update({ displayedTabId: navegateTo, editArticleData: undefined });\r\n}\r\n\r\nfunction callLibs(\r\n src,\r\n stateUpdate,\r\n functionsToCallByLibrary,\r\n extraProps,\r\n callerWidget\r\n) {\r\n return (\r\n <Widget\r\n src={src}\r\n props={{\r\n isTest,\r\n stateUpdate,\r\n functionsToCallByLibrary,\r\n callLibs,\r\n widgets,\r\n callerWidget,\r\n ...extraProps,\r\n }}\r\n />\r\n );\r\n}\r\n\r\nfunction handleSbtSelection(selectedSbt) {\r\n State.update({\r\n sbts: [selectedSbt],\r\n });\r\n}\r\n\r\nfunction handleShareButton(showShareModal, sharedElement) {\r\n //showShareModal is a boolean\r\n //sharedElement is and object like the example: {\r\n // type: string,\r\n // value: number||string,\r\n // }\r\n State.update({ showShareModal, sharedElement });\r\n}\r\n\r\nfunction getLink() {\r\n return `https://near.social/${widgets.sayALot}?${isTest && \"isTest=t&\"}${\r\n state.sharedElement.type\r\n }=${state.sharedElement.value}`;\r\n}\r\n\r\n//===============================================END FUNCTIONS======================================================\r\nif (!context.accountId) {\r\n return (\r\n <>\r\n <Widget\r\n src={widgets.header}\r\n props={{\r\n isTest,\r\n stateUpdate,\r\n handleGoHomeButton,\r\n handlePillNavigation,\r\n brand,\r\n pills: navigationPills,\r\n navigationButtons,\r\n displayedTabId: state.displayedTabId,\r\n handleFilterArticles,\r\n filterParameter: state.filterBy.parameterName,\r\n handleBackButton,\r\n tabs,\r\n sbtsNames,\r\n }}\r\n />\r\n <h2>Log in to see the articles</h2>\r\n </>\r\n );\r\n}\r\n\r\nreturn (\r\n <>\r\n {state.showShareModal && renderShareInteraction()}\r\n <Widget\r\n src={widgets.header}\r\n props={{\r\n isTest,\r\n stateUpdate,\r\n handleGoHomeButton,\r\n handlePillNavigation,\r\n brand,\r\n pills: navigationPills,\r\n navigationButtons,\r\n displayedTabId: state.displayedTabId,\r\n handleFilterArticles,\r\n filterParameter: state.filterBy.parameterName,\r\n handleBackButton,\r\n tabs,\r\n sbtsNames,\r\n }}\r\n />\r\n {state.displayedTabId == tabs.SHOW_ARTICLES_LIST.id && (\r\n <div className=\"my-3 col-lg-8 col-md-8 col-sm-12\">\r\n <Widget\r\n src={widgets.newStyledComponents.Input.Select}\r\n props={{\r\n label: renderSelectorLabel(),\r\n value: sbts[0],\r\n onChange: handleSbtSelection,\r\n options: createSbtOptions(),\r\n }}\r\n />\r\n </div>\r\n )}\r\n {articlesToRender && state.displayedTabId == tabs.SHOW_ARTICLES_LIST.id && (\r\n <Widget\r\n src={widgets.showArticlesList}\r\n props={{\r\n isTest,\r\n articlesToRender,\r\n tabs,\r\n widgets,\r\n addressForArticles,\r\n handleOpenArticle,\r\n handleFilterArticles,\r\n authorForWidget,\r\n initialCreateState,\r\n editArticleData: state.editArticleData,\r\n handleEditArticle,\r\n showCreateArticle: canLoggedUserCreateArticle,\r\n sbtWhiteList,\r\n sbts,\r\n handleShareButton,\r\n canLoggedUserCreateArticles,\r\n filterBy: state.filterBy,\r\n callLibs,\r\n }}\r\n />\r\n )}\r\n {state.articleToRenderData.title &&\r\n state.displayedTabId == tabs.SHOW_ARTICLE.id && (\r\n <Widget\r\n src={widgets.articleView}\r\n props={{\r\n isTest,\r\n widgets,\r\n handleFilterArticles,\r\n articleToRenderData: state.articleToRenderData,\r\n authorForWidget,\r\n handleEditArticle,\r\n handleShareButton,\r\n callLibs,\r\n }}\r\n />\r\n )}\r\n\r\n {state.displayedTabId == tabs.SHOW_ARTICLES_LIST_BY_AUTHORS.id && (\r\n <Widget\r\n src={widgets.showArticlesListSortedByAuthors}\r\n props={{\r\n isTest,\r\n finalArticles,\r\n tabs,\r\n widgets,\r\n handleOpenArticle,\r\n handleFilterArticles,\r\n authorForWidget,\r\n }}\r\n />\r\n )}\r\n\r\n {state.displayedTabId == tabs.ARTICLE_WORKSHOP.id && (\r\n <Widget\r\n src={widgets.create}\r\n props={{\r\n isTest,\r\n addressForArticles,\r\n authorForWidget,\r\n stateUpdate,\r\n widgets,\r\n initialBody: initialBodyAtCreation,\r\n initialCreateState,\r\n editArticleData: state.editArticleData,\r\n callLibs,\r\n handleFilterArticles,\r\n handleEditArticle,\r\n sbtWhiteList,\r\n sbts,\r\n canLoggedUserCreateArticles,\r\n }}\r\n />\r\n )}\r\n\r\n <CallLibrary>\r\n {libSrcArray.map((src) => {\r\n return callLibs(\r\n src,\r\n stateUpdate,\r\n state.functionsToCallByLibrary,\r\n { baseAction: \"sayALotArticle\" },\r\n \"SayALot\"\r\n );\r\n })}\r\n </CallLibrary>\r\n </>\r\n);\r\n"
}
}
}
}
}