From a046614275a770e50338446e99ff275fae488eed Mon Sep 17 00:00:00 2001 From: elcharitas Date: Tue, 27 Feb 2024 07:39:36 +0100 Subject: [PATCH 01/12] add share utils --- packages/frontend/src/api/utils/shareUtils.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 packages/frontend/src/api/utils/shareUtils.ts diff --git a/packages/frontend/src/api/utils/shareUtils.ts b/packages/frontend/src/api/utils/shareUtils.ts new file mode 100644 index 00000000..09d116e7 --- /dev/null +++ b/packages/frontend/src/api/utils/shareUtils.ts @@ -0,0 +1,20 @@ +/** + * Checks if the current environment supports the Web Share API. + * + * @returns Returns true if the Web Share API is supported, otherwise false. + */ +export function canShare() { + return navigator.share != undefined && navigator.canShare != undefined; +} + +/** + * Shares the provided data using the Web Share API if it is supported by the browser. + * + * @param data - The data to be shared. + */ +export function shareData(data: ShareData) { + if (canShare() && navigator.canShare(data)) { + return navigator.share(data); + } + return Promise.reject(new Error("Sharing not supported")); +} From 707ff6c22a177c4e45a6f640e9370d1e317092c7 Mon Sep 17 00:00:00 2001 From: elcharitas Date: Tue, 27 Feb 2024 07:42:10 +0100 Subject: [PATCH 02/12] add test cases --- .../frontend/src/api/utils/shareUtils.test.ts | 31 +++++++++++++++++++ 1 file changed, 31 insertions(+) create mode 100644 packages/frontend/src/api/utils/shareUtils.test.ts diff --git a/packages/frontend/src/api/utils/shareUtils.test.ts b/packages/frontend/src/api/utils/shareUtils.test.ts new file mode 100644 index 00000000..596898a7 --- /dev/null +++ b/packages/frontend/src/api/utils/shareUtils.test.ts @@ -0,0 +1,31 @@ +import { canShare, shareData } from "./shareUtils"; + +describe("shareUtils", () => { + describe("canShare", () => { + it("should return true if the Web Share API is supported", () => { + expect(canShare()).toBe(true); + }); + + it("should return false if the Web Share API is not supported", () => { + // @ts-expect-error navigator is read-only, we're just testing + navigator.share = undefined; + expect(canShare()).toBe(false); + }); + }); + + describe("shareData", () => { + it("should share the provided data using the Web Share API", () => { + expect(shareData({ title: "Test", text: "Test" })).resolves.toBe( + undefined + ); + }); + + it("should not share the data if the Web Share API is not supported", () => { + // @ts-expect-error navigator is read-only, we're just testing + navigator.share = undefined; + expect(shareData({ title: "Test", text: "Test" })).rejects.toThrow( + "Sharing not supported" + ); + }); + }); +}); From 09aa777acdd22f14c3caaef1a735f558c4b12ccb Mon Sep 17 00:00:00 2001 From: elcharitas Date: Tue, 27 Feb 2024 07:45:18 +0100 Subject: [PATCH 03/12] lint fix --- packages/frontend/src/api/utils/shareUtils.test.ts | 2 ++ packages/frontend/src/api/utils/shareUtils.ts | 6 +++--- packages/frontend/src/api/utils/twitterUtils.ts | 4 ++-- packages/frontend/src/components/feeds/FeedComponents.tsx | 4 ++-- 4 files changed, 9 insertions(+), 7 deletions(-) diff --git a/packages/frontend/src/api/utils/shareUtils.test.ts b/packages/frontend/src/api/utils/shareUtils.test.ts index 596898a7..87bffd77 100644 --- a/packages/frontend/src/api/utils/shareUtils.test.ts +++ b/packages/frontend/src/api/utils/shareUtils.test.ts @@ -15,6 +15,7 @@ describe("shareUtils", () => { describe("shareData", () => { it("should share the provided data using the Web Share API", () => { + // eslint-disable-next-line @typescript-eslint/no-floating-promises expect(shareData({ title: "Test", text: "Test" })).resolves.toBe( undefined ); @@ -23,6 +24,7 @@ describe("shareUtils", () => { it("should not share the data if the Web Share API is not supported", () => { // @ts-expect-error navigator is read-only, we're just testing navigator.share = undefined; + // eslint-disable-next-line @typescript-eslint/no-floating-promises expect(shareData({ title: "Test", text: "Test" })).rejects.toThrow( "Sharing not supported" ); diff --git a/packages/frontend/src/api/utils/shareUtils.ts b/packages/frontend/src/api/utils/shareUtils.ts index 09d116e7..471e8fc3 100644 --- a/packages/frontend/src/api/utils/shareUtils.ts +++ b/packages/frontend/src/api/utils/shareUtils.ts @@ -1,15 +1,15 @@ /** * Checks if the current environment supports the Web Share API. - * + * * @returns Returns true if the Web Share API is supported, otherwise false. */ export function canShare() { - return navigator.share != undefined && navigator.canShare != undefined; + return navigator.share !== undefined && navigator.canShare !== undefined; } /** * Shares the provided data using the Web Share API if it is supported by the browser. - * + * * @param data - The data to be shared. */ export function shareData(data: ShareData) { diff --git a/packages/frontend/src/api/utils/twitterUtils.ts b/packages/frontend/src/api/utils/twitterUtils.ts index 78baca39..5b9baf89 100644 --- a/packages/frontend/src/api/utils/twitterUtils.ts +++ b/packages/frontend/src/api/utils/twitterUtils.ts @@ -124,8 +124,8 @@ export const parseRemoteTweetV1 = ( attachments: { media_keys: t.attachments?.media_keys ?? [], attachments: - r.includes.media?.filter((m) => - t.attachments?.media_keys?.includes(m.media_key) + r.includes.media?.filter( + (m) => t.attachments?.media_keys?.includes(m.media_key) ) ?? [], }, author: r.includes.users.find( diff --git a/packages/frontend/src/components/feeds/FeedComponents.tsx b/packages/frontend/src/components/feeds/FeedComponents.tsx index f6f04ef4..eca85cad 100644 --- a/packages/frontend/src/components/feeds/FeedComponents.tsx +++ b/packages/frontend/src/components/feeds/FeedComponents.tsx @@ -99,8 +99,8 @@ export function TweetMedia< E = T extends "video" ? HTMLVideoElement : T extends "audio" - ? HTMLAudioElement - : HTMLImageElement, + ? HTMLAudioElement + : HTMLImageElement, >({ mediaType, className, ...props }: ITweetMedia) { const MediaComponent = mediaType as unknown as FC> | null; return ( From b41ae5548bd311fdc2e5ae95325dcf032a8fea10 Mon Sep 17 00:00:00 2001 From: elcharitas Date: Wed, 28 Feb 2024 12:42:30 +0100 Subject: [PATCH 04/12] wip --- .../src/mobile-components/Superfeed.tsx | 19 ++++++++++++ .../src/mobile-components/feed/BlogCard.tsx | 9 +++--- .../src/mobile-components/feed/EventCard.tsx | 11 ++++--- .../src/mobile-components/feed/FeedCard.tsx | 30 +++++++++++-------- .../src/mobile-components/feed/ImageCard.tsx | 11 ++++--- .../src/mobile-components/feed/MarketCard.tsx | 11 ++++--- .../src/mobile-components/feed/NewsCard.tsx | 11 ++++--- .../mobile-components/feed/PodcastCard.tsx | 10 ++++--- .../src/mobile-components/feed/SocialCard.tsx | 11 ++++--- .../src/mobile-components/feed/VideoCard.tsx | 11 ++++--- 10 files changed, 90 insertions(+), 44 deletions(-) diff --git a/packages/frontend/src/mobile-components/Superfeed.tsx b/packages/frontend/src/mobile-components/Superfeed.tsx index d7d235cc..b7bdd2b2 100644 --- a/packages/frontend/src/mobile-components/Superfeed.tsx +++ b/packages/frontend/src/mobile-components/Superfeed.tsx @@ -4,6 +4,9 @@ import { AudioPlayerProvider } from "react-use-audio-player"; import { useOnScreen } from "src/api/hooks"; import { TSuperfeedItem } from "src/api/types"; import { shouldFetchMoreItems } from "src/api/utils/itemUtils"; +import { Logger } from "src/api/utils/logging"; +import { shareData } from "src/api/utils/shareUtils"; +import { toast } from "src/api/utils/toastUtils"; import { ReactComponent as SettingsSVG } from "src/assets/icons/settings.svg"; import { ReactComponent as Settings2SVG } from "src/assets/icons/settings3.svg"; import { FeedCard } from "./feed/FeedCard"; @@ -87,6 +90,22 @@ const SuperfeedModule: FC = ({ item={item} selectedPodcast={selectedPodcast} setSelectedPodcast={setSelectedPodcast} + onLike={() => {}} + onShare={async () => { + try { + await shareData({ + title: item.title, + text: item.shortDescription, + url: item.url, + }); + } catch (e) { + Logger.error( + "SuperfeedModule::FeedCard: error sharing item", + e + ); + toast("Error sharing item"); + } + }} /> ))} diff --git a/packages/frontend/src/mobile-components/feed/BlogCard.tsx b/packages/frontend/src/mobile-components/feed/BlogCard.tsx index 4267d9a5..685182a4 100644 --- a/packages/frontend/src/mobile-components/feed/BlogCard.tsx +++ b/packages/frontend/src/mobile-components/feed/BlogCard.tsx @@ -14,7 +14,9 @@ import { export const BlogCard: FC<{ item: TSuperfeedItem; -}> = ({ item }) => { + onLike: () => void; + onShare: () => void; +}> = ({ item, onLike, onShare }) => { const { title, tags, @@ -27,7 +29,6 @@ export const BlogCard: FC<{ shortDescription, date, } = item; - const onLike = () => {}; const isLiked = false; return ( @@ -72,7 +73,7 @@ export const BlogCard: FC<{ { ); }; -export const EventCard: FC<{ item: TSuperfeedItem }> = ({ item }) => { +export const EventCard: FC<{ + item: TSuperfeedItem; + onLike: () => void; + onShare: () => void; +}> = ({ item, onLike, onShare }) => { const { title, tags, @@ -56,7 +60,6 @@ export const EventCard: FC<{ item: TSuperfeedItem }> = ({ item }) => { const location = "location"; const category = "category"; - const onLike = () => {}; const isLiked = false; return ( @@ -116,7 +119,7 @@ export const EventCard: FC<{ item: TSuperfeedItem }> = ({ item }) => { = ({ item }) => { >; + onLike: () => MaybeAsync; + onShare: () => MaybeAsync; } export const FeedCard: FC = ({ item, selectedPodcast, setSelectedPodcast, + onLike, + onShare, }) => { switch (item.type) { case EFeedItemType.NEWS: - return ; + return ; case EFeedItemType.BLOG: - return ; + return ; case EFeedItemType.FORUM: - return ; + return ; case EFeedItemType.PERSON: - return ; + return ; case EFeedItemType.VIDEO: - return ; + return ; case EFeedItemType.PODCAST: return ( ); case EFeedItemType.EVENT: - return ; + return ; case EFeedItemType.MEME: - return ; + return ; case EFeedItemType.IMAGE: - return ; + return ; case EFeedItemType.REDDIT: - return ; + return ; case EFeedItemType.DISCORD: - return ; + return ; case EFeedItemType.MARKET: - return ; + return ; case EFeedItemType.TVL: - return ; + return ; default: return null; } diff --git a/packages/frontend/src/mobile-components/feed/ImageCard.tsx b/packages/frontend/src/mobile-components/feed/ImageCard.tsx index 20cf505e..6fe18397 100644 --- a/packages/frontend/src/mobile-components/feed/ImageCard.tsx +++ b/packages/frontend/src/mobile-components/feed/ImageCard.tsx @@ -13,7 +13,11 @@ import { getFeedItemIcon, } from "./FeedElements"; -export const ImageCard: FC<{ item: TSuperfeedItem }> = ({ item }) => { +export const ImageCard: FC<{ + item: TSuperfeedItem; + onLike: () => void; + onShare: () => void; +}> = ({ item, onLike, onShare }) => { const { title, tags, @@ -26,7 +30,6 @@ export const ImageCard: FC<{ item: TSuperfeedItem }> = ({ item }) => { shortDescription, } = item; - const onLike = () => {}; const isLiked = false; return ( @@ -80,7 +83,7 @@ export const ImageCard: FC<{ item: TSuperfeedItem }> = ({ item }) => { = ({ item }) => { { return parsedHistory; }; -export const MarketCard: FC<{ item: TSuperfeedItem }> = ({ item }) => { +export const MarketCard: FC<{ + item: TSuperfeedItem; + onLike: () => void; + onShare: () => void; +}> = ({ item, onLike, onShare }) => { const isTVL = item.type === EFeedItemType.TVL; const { @@ -37,7 +41,6 @@ export const MarketCard: FC<{ item: TSuperfeedItem }> = ({ item }) => { data: coinData, } = item; - const onLike = () => {}; const isLiked = false; const isDown = shortDescription?.includes("down"); @@ -133,7 +136,7 @@ export const MarketCard: FC<{ item: TSuperfeedItem }> = ({ item }) => { = ({ item }) => { = ({ item }) => { +export const NewsCard: FC<{ + item: TSuperfeedItem; + onLike: () => void; + onShare: () => void; +}> = ({ item, onLike, onShare }) => { const { title, tags, @@ -29,7 +33,6 @@ export const NewsCard: FC<{ item: TSuperfeedItem }> = ({ item }) => { date, } = item; - const onLike = () => {}; const isLiked = false; return ( @@ -80,7 +83,7 @@ export const NewsCard: FC<{ item: TSuperfeedItem }> = ({ item }) => { = ({ item }) => { >; + onLike: () => void; + onShare: () => void; } const PlayPauseButton: FC<{ @@ -63,6 +65,8 @@ export const PodcastCard: FC = ({ item, selectedPodcast, setSelectedPodcast, + onLike, + onShare, }) => { const { title, @@ -112,8 +116,6 @@ export const PodcastCard: FC = ({ setSelectedPodcast(item); togglePlayPause(); }; - - const onLike = () => {}; const isLiked = false; return ( @@ -203,7 +205,7 @@ export const PodcastCard: FC = ({ = ({ = ({ item }) => { +export const SocialCard: FC<{ + item: TSuperfeedItem; + onLike: () => void; + onShare: () => void; +}> = ({ item, onLike, onShare }) => { const { title, tags, @@ -30,7 +34,6 @@ export const SocialCard: FC<{ item: TSuperfeedItem }> = ({ item }) => { date, } = item; - const onLike = () => {}; const isLiked = false; return ( @@ -91,7 +94,7 @@ export const SocialCard: FC<{ item: TSuperfeedItem }> = ({ item }) => { = ({ item }) => { ); -export const VideoCard: FC<{ item: TSuperfeedItem }> = ({ item }) => { +export const VideoCard: FC<{ + item: TSuperfeedItem; + onLike: () => void; + onShare: () => void; +}> = ({ item, onLike, onShare }) => { const { title, tags, @@ -48,7 +52,6 @@ export const VideoCard: FC<{ item: TSuperfeedItem }> = ({ item }) => { shortDescription, } = item; - const onLike = () => {}; const isLiked = false; /** @@ -116,7 +119,7 @@ export const VideoCard: FC<{ item: TSuperfeedItem }> = ({ item }) => { = ({ item }) => { Date: Wed, 28 Feb 2024 12:49:05 +0100 Subject: [PATCH 05/12] fixes --- packages/frontend/src/mobile-components/feed/BlogCard.tsx | 4 ++-- .../frontend/src/mobile-components/feed/EventCard.tsx | 4 ++-- .../frontend/src/mobile-components/feed/FeedElements.tsx | 6 +++--- .../frontend/src/mobile-components/feed/ImageCard.tsx | 4 ++-- .../frontend/src/mobile-components/feed/MarketCard.tsx | 4 ++-- packages/frontend/src/mobile-components/feed/NewsCard.tsx | 4 ++-- .../frontend/src/mobile-components/feed/PodcastCard.tsx | 4 ++-- .../frontend/src/mobile-components/feed/SocialCard.tsx | 4 ++-- .../frontend/src/mobile-components/feed/VideoCard.tsx | 6 +++--- packages/ui-kit/src/mobile-components/button/buttons.tsx | 8 ++++---- 10 files changed, 24 insertions(+), 24 deletions(-) diff --git a/packages/frontend/src/mobile-components/feed/BlogCard.tsx b/packages/frontend/src/mobile-components/feed/BlogCard.tsx index 685182a4..daa61e48 100644 --- a/packages/frontend/src/mobile-components/feed/BlogCard.tsx +++ b/packages/frontend/src/mobile-components/feed/BlogCard.tsx @@ -14,8 +14,8 @@ import { export const BlogCard: FC<{ item: TSuperfeedItem; - onLike: () => void; - onShare: () => void; + onLike: () => MaybeAsync; + onShare: () => MaybeAsync; }> = ({ item, onLike, onShare }) => { const { title, diff --git a/packages/frontend/src/mobile-components/feed/EventCard.tsx b/packages/frontend/src/mobile-components/feed/EventCard.tsx index c3b8aa90..94296e6c 100644 --- a/packages/frontend/src/mobile-components/feed/EventCard.tsx +++ b/packages/frontend/src/mobile-components/feed/EventCard.tsx @@ -38,8 +38,8 @@ const eventDateFormatter = (date: string) => { export const EventCard: FC<{ item: TSuperfeedItem; - onLike: () => void; - onShare: () => void; + onLike: () => MaybeAsync; + onShare: () => MaybeAsync; }> = ({ item, onLike, onShare }) => { const { title, diff --git a/packages/frontend/src/mobile-components/feed/FeedElements.tsx b/packages/frontend/src/mobile-components/feed/FeedElements.tsx index 7a474f3d..2cc21454 100644 --- a/packages/frontend/src/mobile-components/feed/FeedElements.tsx +++ b/packages/frontend/src/mobile-components/feed/FeedElements.tsx @@ -17,9 +17,9 @@ export const getFeedItemIcon = (type: EFeedItemType, isDown?: boolean) => { }; export const ActionButtons: FC<{ - onLike: () => void; - onCommentClick: () => void; - onShare: () => void; + onLike: () => MaybeAsync; + onCommentClick: () => MaybeAsync; + onShare: () => MaybeAsync; likes: number; comments: number; isLiked: boolean; diff --git a/packages/frontend/src/mobile-components/feed/ImageCard.tsx b/packages/frontend/src/mobile-components/feed/ImageCard.tsx index 6fe18397..c9dc5647 100644 --- a/packages/frontend/src/mobile-components/feed/ImageCard.tsx +++ b/packages/frontend/src/mobile-components/feed/ImageCard.tsx @@ -15,8 +15,8 @@ import { export const ImageCard: FC<{ item: TSuperfeedItem; - onLike: () => void; - onShare: () => void; + onLike: () => MaybeAsync; + onShare: () => MaybeAsync; }> = ({ item, onLike, onShare }) => { const { title, diff --git a/packages/frontend/src/mobile-components/feed/MarketCard.tsx b/packages/frontend/src/mobile-components/feed/MarketCard.tsx index 156b5dbe..8869bbc7 100644 --- a/packages/frontend/src/mobile-components/feed/MarketCard.tsx +++ b/packages/frontend/src/mobile-components/feed/MarketCard.tsx @@ -25,8 +25,8 @@ const parseHistory = (history: string): [number, number][] => { export const MarketCard: FC<{ item: TSuperfeedItem; - onLike: () => void; - onShare: () => void; + onLike: () => MaybeAsync; + onShare: () => MaybeAsync; }> = ({ item, onLike, onShare }) => { const isTVL = item.type === EFeedItemType.TVL; diff --git a/packages/frontend/src/mobile-components/feed/NewsCard.tsx b/packages/frontend/src/mobile-components/feed/NewsCard.tsx index 06eb9e9a..1d26b749 100644 --- a/packages/frontend/src/mobile-components/feed/NewsCard.tsx +++ b/packages/frontend/src/mobile-components/feed/NewsCard.tsx @@ -16,8 +16,8 @@ import { export const NewsCard: FC<{ item: TSuperfeedItem; - onLike: () => void; - onShare: () => void; + onLike: () => MaybeAsync; + onShare: () => MaybeAsync; }> = ({ item, onLike, onShare }) => { const { title, diff --git a/packages/frontend/src/mobile-components/feed/PodcastCard.tsx b/packages/frontend/src/mobile-components/feed/PodcastCard.tsx index fc634404..f44a824f 100644 --- a/packages/frontend/src/mobile-components/feed/PodcastCard.tsx +++ b/packages/frontend/src/mobile-components/feed/PodcastCard.tsx @@ -27,8 +27,8 @@ interface IPodcastCard { setSelectedPodcast: React.Dispatch< React.SetStateAction >; - onLike: () => void; - onShare: () => void; + onLike: () => MaybeAsync; + onShare: () => MaybeAsync; } const PlayPauseButton: FC<{ diff --git a/packages/frontend/src/mobile-components/feed/SocialCard.tsx b/packages/frontend/src/mobile-components/feed/SocialCard.tsx index 559a37b5..f0786d1f 100644 --- a/packages/frontend/src/mobile-components/feed/SocialCard.tsx +++ b/packages/frontend/src/mobile-components/feed/SocialCard.tsx @@ -17,8 +17,8 @@ import { export const SocialCard: FC<{ item: TSuperfeedItem; - onLike: () => void; - onShare: () => void; + onLike: () => MaybeAsync; + onShare: () => MaybeAsync; }> = ({ item, onLike, onShare }) => { const { title, diff --git a/packages/frontend/src/mobile-components/feed/VideoCard.tsx b/packages/frontend/src/mobile-components/feed/VideoCard.tsx index 399e4c4c..bce6f989 100644 --- a/packages/frontend/src/mobile-components/feed/VideoCard.tsx +++ b/packages/frontend/src/mobile-components/feed/VideoCard.tsx @@ -35,8 +35,8 @@ const VideoPlaceholder: FC<{ export const VideoCard: FC<{ item: TSuperfeedItem; - onLike: () => void; - onShare: () => void; + onLike: () => MaybeAsync; + onShare: () => MaybeAsync; }> = ({ item, onLike, onShare }) => { const { title, @@ -101,7 +101,7 @@ export const VideoCard: FC<{ {open ? null : ( {}} /> )} diff --git a/packages/ui-kit/src/mobile-components/button/buttons.tsx b/packages/ui-kit/src/mobile-components/button/buttons.tsx index 9f638424..19d0e79c 100644 --- a/packages/ui-kit/src/mobile-components/button/buttons.tsx +++ b/packages/ui-kit/src/mobile-components/button/buttons.tsx @@ -2,10 +2,10 @@ import { FC, ReactNode } from "react"; import { Link } from "react-router-dom"; import { twMerge } from "tailwind-merge"; -export const ActionButton: FC<{ children: ReactNode; onClick: () => void }> = ({ - onClick, - children, -}) => { +export const ActionButton: FC<{ + children: ReactNode; + onClick: () => MaybeAsync; +}> = ({ onClick, children }) => { const handleClick = ( e: React.MouseEvent ) => { From 8355847055f3cb30305f820a0cdd7823dc91c5ee Mon Sep 17 00:00:00 2001 From: elcharitas Date: Wed, 28 Feb 2024 12:53:37 +0100 Subject: [PATCH 06/12] void button onClick --- packages/ui-kit/src/mobile-components/button/buttons.tsx | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/ui-kit/src/mobile-components/button/buttons.tsx b/packages/ui-kit/src/mobile-components/button/buttons.tsx index 19d0e79c..81eb5fe8 100644 --- a/packages/ui-kit/src/mobile-components/button/buttons.tsx +++ b/packages/ui-kit/src/mobile-components/button/buttons.tsx @@ -11,6 +11,7 @@ export const ActionButton: FC<{ ) => { e.preventDefault(); e.stopPropagation(); + // eslint-disable-next-line @typescript-eslint/no-floating-promises onClick(); }; return ( From d9dc247a4ca6f43c59b96dcbe8a5afc9a8b91862 Mon Sep 17 00:00:00 2001 From: elcharitas Date: Thu, 29 Feb 2024 09:56:01 +0100 Subject: [PATCH 07/12] add logging for share --- .../src/api/hooks/useActivityLogger.ts | 34 ++++++++++++++++++- .../src/api/services/activity-log/types.ts | 12 ++++++- .../src/mobile-components/Superfeed.tsx | 21 ++---------- .../mobile-containers/SuperfeedContainer.tsx | 32 ++++++++++++++--- 4 files changed, 75 insertions(+), 24 deletions(-) diff --git a/packages/frontend/src/api/hooks/useActivityLogger.ts b/packages/frontend/src/api/hooks/useActivityLogger.ts index 8aefb78a..b0dadc60 100644 --- a/packages/frontend/src/api/hooks/useActivityLogger.ts +++ b/packages/frontend/src/api/hooks/useActivityLogger.ts @@ -3,7 +3,11 @@ import { EActivityLogEventTypes, EActivityLogObjectTypes, } from "src/api/services/activity-log/types"; -import { ECookieChoice, EWalletConnectionMethod } from "src/api/types"; +import { + ECookieChoice, + EWalletConnectionMethod, + TSuperfeedItem, +} from "src/api/types"; import { Logger } from "../utils/logging"; interface IActivityLogger { @@ -11,6 +15,7 @@ interface IActivityLogger { logViewVisited: (id: number) => void; logKeywordSelected: (id: number) => void; logWalletConnection: (method: EWalletConnectionMethod) => void; + logShareSuperfeedItem: (item: TSuperfeedItem) => void; } export const useActivityLogger = (): IActivityLogger => { @@ -103,10 +108,37 @@ export const useActivityLogger = (): IActivityLogger => { ); }; + const logShareSuperfeedItem = (item: TSuperfeedItem) => { + sendActivityLog({ + event_type: EActivityLogEventTypes.ShareSuperfeedItem, + object_type: EActivityLogObjectTypes.ShareSuperfeedItem, + object_id: item.id, + data: { + title: item.title, + text: item.shortDescription ?? item.title, + url: item.url, + }, + }) + .unwrap() + .then((resp) => + Logger.debug( + "useActivityLogger::logShareSuperfeedItem: updated share superfeed item activity log", + resp + ) + ) + .catch((err) => + Logger.error( + "useActivityLogger::logShareSuperfeedItem: error updating share superfeed item activity log", + err + ) + ); + }; + return { logViewVisited, logCookieChoice, logKeywordSelected, logWalletConnection, + logShareSuperfeedItem, }; }; diff --git a/packages/frontend/src/api/services/activity-log/types.ts b/packages/frontend/src/api/services/activity-log/types.ts index 8121ea17..d45159d7 100644 --- a/packages/frontend/src/api/services/activity-log/types.ts +++ b/packages/frontend/src/api/services/activity-log/types.ts @@ -4,6 +4,7 @@ export enum EActivityLogEventTypes { KeywordSelected = "KEYWORD_SELECTED", CookieChoiceSet = "COOKIE_CHOICE_SET", WalletConnection = "WALLET_CONNECT", + ShareSuperfeedItem = "SHARE_ITEM", } export enum EActivityLogObjectTypes { @@ -11,6 +12,7 @@ export enum EActivityLogObjectTypes { Widget, View, WalletConnection, + ShareSuperfeedItem, } export type TKeywordActivityLog = { @@ -45,12 +47,20 @@ export type TWalletConnectionActivityLog = { data?: JSONValue; }; +export type TShareSuperfeedItemActivityLog = { + event_type: EActivityLogEventTypes.ShareSuperfeedItem; + object_type: EActivityLogObjectTypes.ShareSuperfeedItem; + object_id: number; + data: JSONValue; +}; + export type TRemoteActivityLog = | TKeywordActivityLog | TWidgetActivityLog | TViewActivityLog | TCookieActivityLog - | TWalletConnectionActivityLog; + | TWalletConnectionActivityLog + | TShareSuperfeedItemActivityLog; export type TActivityLogRequest = TRemoteActivityLog; export type TActivityLogResponse = TRemoteActivityLog; diff --git a/packages/frontend/src/mobile-components/Superfeed.tsx b/packages/frontend/src/mobile-components/Superfeed.tsx index b7bdd2b2..f276d91b 100644 --- a/packages/frontend/src/mobile-components/Superfeed.tsx +++ b/packages/frontend/src/mobile-components/Superfeed.tsx @@ -4,9 +4,6 @@ import { AudioPlayerProvider } from "react-use-audio-player"; import { useOnScreen } from "src/api/hooks"; import { TSuperfeedItem } from "src/api/types"; import { shouldFetchMoreItems } from "src/api/utils/itemUtils"; -import { Logger } from "src/api/utils/logging"; -import { shareData } from "src/api/utils/shareUtils"; -import { toast } from "src/api/utils/toastUtils"; import { ReactComponent as SettingsSVG } from "src/assets/icons/settings.svg"; import { ReactComponent as Settings2SVG } from "src/assets/icons/settings3.svg"; import { FeedCard } from "./feed/FeedCard"; @@ -16,6 +13,7 @@ interface ISuperfeedModule { feed: TSuperfeedItem[] | undefined; handlePaginate: (type: "next" | "previous") => void; toggleShowFeedFilters: () => void; + onShareItem: (item: TSuperfeedItem) => void; selectedPodcast: TSuperfeedItem | null; setSelectedPodcast: React.Dispatch< React.SetStateAction @@ -67,6 +65,7 @@ const SuperfeedModule: FC = ({ toggleShowFeedFilters, selectedPodcast, setSelectedPodcast, + onShareItem, }) => { const handleScrollEvent = useCallback( ({ currentTarget }: FormEvent) => { @@ -91,21 +90,7 @@ const SuperfeedModule: FC = ({ selectedPodcast={selectedPodcast} setSelectedPodcast={setSelectedPodcast} onLike={() => {}} - onShare={async () => { - try { - await shareData({ - title: item.title, - text: item.shortDescription, - url: item.url, - }); - } catch (e) { - Logger.error( - "SuperfeedModule::FeedCard: error sharing item", - e - ); - toast("Error sharing item"); - } - }} + onShare={() => onShareItem(item)} /> ))} diff --git a/packages/frontend/src/mobile-containers/SuperfeedContainer.tsx b/packages/frontend/src/mobile-containers/SuperfeedContainer.tsx index 8150e9c0..fdccb4e7 100644 --- a/packages/frontend/src/mobile-containers/SuperfeedContainer.tsx +++ b/packages/frontend/src/mobile-containers/SuperfeedContainer.tsx @@ -1,12 +1,15 @@ -import { FC, useEffect, useRef, useState } from "react"; +import { FC, useCallback, useEffect, useRef, useState } from "react"; import { useHistory } from "react-router-dom"; import { AudioPlayerProvider } from "react-use-audio-player"; -import { usePagination } from "src/api/hooks"; +import { useActivityLogger, usePagination } from "src/api/hooks"; import { useKeywordSearch } from "src/api/hooks/useKeywordSearch"; import { useGetSuperfeedListQuery } from "src/api/services"; import { selectedLocalFiltersSelector } from "src/api/store"; import { useAppSelector } from "src/api/store/hooks"; import { TSuperfeedItem } from "src/api/types"; +import { Logger } from "src/api/utils/logging"; +import { shareData } from "src/api/utils/shareUtils"; +import { toast } from "src/api/utils/toastUtils"; import FilterSearchBar from "src/mobile-components/FilterSearchBar"; import SuperfeedModule from "src/mobile-components/Superfeed"; import { STATIC_FILTER_OPTIONS } from "src/mobile-components/user-filters-modal/filterOptions"; @@ -24,8 +27,10 @@ const SuperfeedContainer: FC<{ const selectedLocalFilters = useAppSelector(selectedLocalFiltersSelector); const prevTagsRef = useRef(tags); - const [selectedPodcast, setSelectedPodcast] = - useState(null); + const [ + selectedPodcast, + setSelectedPodcast, + ] = useState(null); const contentTypes = Object.values(STATIC_FILTER_OPTIONS.media.options) .filter((op) => selectedLocalFilters.mediaTypes.includes(op.slug)) .map((op) => op.contentType) @@ -55,6 +60,8 @@ const SuperfeedContainer: FC<{ isSuccess ); + const { logShareSuperfeedItem } = useActivityLogger(); + const feedDataForCurrentPage = [...(feedDataResponse?.results ?? [])]; const [feedData, setfeedData] = useState([]); @@ -75,6 +82,22 @@ const SuperfeedContainer: FC<{ setfeedData((prevState) => [...prevState, ...feedDataForCurrentPage]); prevFeedDataResponseRef.current = feedDataResponse?.results; } + + const shareItem = useCallback(async (item: TSuperfeedItem) => { + try { + await shareData({ + title: item.title, + text: item.shortDescription, + url: item.url, + }); + + // Log the share + logShareSuperfeedItem(item); + } catch (e) { + Logger.error("SuperfeedModule::FeedCard: error sharing item", e); + toast("Error sharing item"); + } + }, []); // set current page 350ms after next page is set. // RTK should cache requests, so we don't need to be too careful about rerenders. useEffect(() => { @@ -136,6 +159,7 @@ const SuperfeedContainer: FC<{ toggleShowFeedFilters={onToggleFeedFilters} selectedPodcast={selectedPodcast} setSelectedPodcast={setSelectedPodcast} + onShareItem={shareItem} /> ); From 13331a8986562bf2c9cac98b7b24f96367edf559 Mon Sep 17 00:00:00 2001 From: elcharitas Date: Thu, 29 Feb 2024 09:58:10 +0100 Subject: [PATCH 08/12] fixes --- .../frontend/src/mobile-containers/SuperfeedContainer.tsx | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/packages/frontend/src/mobile-containers/SuperfeedContainer.tsx b/packages/frontend/src/mobile-containers/SuperfeedContainer.tsx index fdccb4e7..3f834560 100644 --- a/packages/frontend/src/mobile-containers/SuperfeedContainer.tsx +++ b/packages/frontend/src/mobile-containers/SuperfeedContainer.tsx @@ -27,10 +27,8 @@ const SuperfeedContainer: FC<{ const selectedLocalFilters = useAppSelector(selectedLocalFiltersSelector); const prevTagsRef = useRef(tags); - const [ - selectedPodcast, - setSelectedPodcast, - ] = useState(null); + const [selectedPodcast, setSelectedPodcast] = + useState(null); const contentTypes = Object.values(STATIC_FILTER_OPTIONS.media.options) .filter((op) => selectedLocalFilters.mediaTypes.includes(op.slug)) .map((op) => op.contentType) @@ -97,7 +95,7 @@ const SuperfeedContainer: FC<{ Logger.error("SuperfeedModule::FeedCard: error sharing item", e); toast("Error sharing item"); } - }, []); + }, [logShareSuperfeedItem]); // set current page 350ms after next page is set. // RTK should cache requests, so we don't need to be too careful about rerenders. useEffect(() => { From 82e5c5a997e366b059e44e2ef970d171d6a70957 Mon Sep 17 00:00:00 2001 From: elcharitas Date: Thu, 29 Feb 2024 10:01:44 +0100 Subject: [PATCH 09/12] cleanup --- .../src/mobile-components/Superfeed.tsx | 2 +- .../mobile-containers/SuperfeedContainer.tsx | 36 +++++++++++-------- 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/packages/frontend/src/mobile-components/Superfeed.tsx b/packages/frontend/src/mobile-components/Superfeed.tsx index f276d91b..36e5ab09 100644 --- a/packages/frontend/src/mobile-components/Superfeed.tsx +++ b/packages/frontend/src/mobile-components/Superfeed.tsx @@ -13,7 +13,7 @@ interface ISuperfeedModule { feed: TSuperfeedItem[] | undefined; handlePaginate: (type: "next" | "previous") => void; toggleShowFeedFilters: () => void; - onShareItem: (item: TSuperfeedItem) => void; + onShareItem: (item: TSuperfeedItem) => Promise; selectedPodcast: TSuperfeedItem | null; setSelectedPodcast: React.Dispatch< React.SetStateAction diff --git a/packages/frontend/src/mobile-containers/SuperfeedContainer.tsx b/packages/frontend/src/mobile-containers/SuperfeedContainer.tsx index 3f834560..b75b56d7 100644 --- a/packages/frontend/src/mobile-containers/SuperfeedContainer.tsx +++ b/packages/frontend/src/mobile-containers/SuperfeedContainer.tsx @@ -81,21 +81,27 @@ const SuperfeedContainer: FC<{ prevFeedDataResponseRef.current = feedDataResponse?.results; } - const shareItem = useCallback(async (item: TSuperfeedItem) => { - try { - await shareData({ - title: item.title, - text: item.shortDescription, - url: item.url, - }); - - // Log the share - logShareSuperfeedItem(item); - } catch (e) { - Logger.error("SuperfeedModule::FeedCard: error sharing item", e); - toast("Error sharing item"); - } - }, [logShareSuperfeedItem]); + const shareItem = useCallback( + async (item: TSuperfeedItem) => { + try { + await shareData({ + title: item.title, + text: item.shortDescription, + url: item.url, + }); + + // Log the share + logShareSuperfeedItem(item); + } catch (e) { + Logger.error( + "SuperfeedModule::FeedCard: error sharing item", + e + ); + toast("Error sharing item"); + } + }, + [logShareSuperfeedItem] + ); // set current page 350ms after next page is set. // RTK should cache requests, so we don't need to be too careful about rerenders. useEffect(() => { From 61983a2b96cbc7cf9b69cef0256d64276426479f Mon Sep 17 00:00:00 2001 From: elcharitas Date: Thu, 29 Feb 2024 13:13:34 +0100 Subject: [PATCH 10/12] fix up lints issues --- packages/frontend/src/api/utils/twitterUtils.ts | 4 ++-- packages/frontend/src/components/feeds/FeedComponents.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/frontend/src/api/utils/twitterUtils.ts b/packages/frontend/src/api/utils/twitterUtils.ts index 5b9baf89..78baca39 100644 --- a/packages/frontend/src/api/utils/twitterUtils.ts +++ b/packages/frontend/src/api/utils/twitterUtils.ts @@ -124,8 +124,8 @@ export const parseRemoteTweetV1 = ( attachments: { media_keys: t.attachments?.media_keys ?? [], attachments: - r.includes.media?.filter( - (m) => t.attachments?.media_keys?.includes(m.media_key) + r.includes.media?.filter((m) => + t.attachments?.media_keys?.includes(m.media_key) ) ?? [], }, author: r.includes.users.find( diff --git a/packages/frontend/src/components/feeds/FeedComponents.tsx b/packages/frontend/src/components/feeds/FeedComponents.tsx index eca85cad..f6f04ef4 100644 --- a/packages/frontend/src/components/feeds/FeedComponents.tsx +++ b/packages/frontend/src/components/feeds/FeedComponents.tsx @@ -99,8 +99,8 @@ export function TweetMedia< E = T extends "video" ? HTMLVideoElement : T extends "audio" - ? HTMLAudioElement - : HTMLImageElement, + ? HTMLAudioElement + : HTMLImageElement, >({ mediaType, className, ...props }: ITweetMedia) { const MediaComponent = mediaType as unknown as FC> | null; return ( From 7a1e1d95c348a6196989096390d0d67ca1bfaf0b Mon Sep 17 00:00:00 2001 From: elcharitas Date: Mon, 4 Mar 2024 13:54:45 +0100 Subject: [PATCH 11/12] fixes --- packages/frontend/src/api/utils/twitterUtils.ts | 4 ++-- packages/frontend/src/components/feeds/FeedComponents.tsx | 4 ++-- packages/frontend/src/mobile-components/Superfeed.tsx | 2 ++ 3 files changed, 6 insertions(+), 4 deletions(-) diff --git a/packages/frontend/src/api/utils/twitterUtils.ts b/packages/frontend/src/api/utils/twitterUtils.ts index 78baca39..5b9baf89 100644 --- a/packages/frontend/src/api/utils/twitterUtils.ts +++ b/packages/frontend/src/api/utils/twitterUtils.ts @@ -124,8 +124,8 @@ export const parseRemoteTweetV1 = ( attachments: { media_keys: t.attachments?.media_keys ?? [], attachments: - r.includes.media?.filter((m) => - t.attachments?.media_keys?.includes(m.media_key) + r.includes.media?.filter( + (m) => t.attachments?.media_keys?.includes(m.media_key) ) ?? [], }, author: r.includes.users.find( diff --git a/packages/frontend/src/components/feeds/FeedComponents.tsx b/packages/frontend/src/components/feeds/FeedComponents.tsx index f6f04ef4..eca85cad 100644 --- a/packages/frontend/src/components/feeds/FeedComponents.tsx +++ b/packages/frontend/src/components/feeds/FeedComponents.tsx @@ -99,8 +99,8 @@ export function TweetMedia< E = T extends "video" ? HTMLVideoElement : T extends "audio" - ? HTMLAudioElement - : HTMLImageElement, + ? HTMLAudioElement + : HTMLImageElement, >({ mediaType, className, ...props }: ITweetMedia) { const MediaComponent = mediaType as unknown as FC> | null; return ( diff --git a/packages/frontend/src/mobile-components/Superfeed.tsx b/packages/frontend/src/mobile-components/Superfeed.tsx index 3374cb64..07b2f84e 100644 --- a/packages/frontend/src/mobile-components/Superfeed.tsx +++ b/packages/frontend/src/mobile-components/Superfeed.tsx @@ -87,6 +87,8 @@ const SuperfeedModule: FC = ({ item={item} selectedPodcast={selectedPodcast} setSelectedPodcast={setSelectedPodcast} + onLike={() => {}} + onShare={() => onShareItem(item)} /> ))} From c401acb2e4f8cdd5692fb6aa74dcb723a4ded13c Mon Sep 17 00:00:00 2001 From: elcharitas Date: Mon, 4 Mar 2024 14:37:23 +0100 Subject: [PATCH 12/12] more fixes --- packages/frontend/src/api/utils/twitterUtils.ts | 4 ++-- packages/frontend/src/components/feeds/FeedComponents.tsx | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/packages/frontend/src/api/utils/twitterUtils.ts b/packages/frontend/src/api/utils/twitterUtils.ts index 5b9baf89..78baca39 100644 --- a/packages/frontend/src/api/utils/twitterUtils.ts +++ b/packages/frontend/src/api/utils/twitterUtils.ts @@ -124,8 +124,8 @@ export const parseRemoteTweetV1 = ( attachments: { media_keys: t.attachments?.media_keys ?? [], attachments: - r.includes.media?.filter( - (m) => t.attachments?.media_keys?.includes(m.media_key) + r.includes.media?.filter((m) => + t.attachments?.media_keys?.includes(m.media_key) ) ?? [], }, author: r.includes.users.find( diff --git a/packages/frontend/src/components/feeds/FeedComponents.tsx b/packages/frontend/src/components/feeds/FeedComponents.tsx index eca85cad..f6f04ef4 100644 --- a/packages/frontend/src/components/feeds/FeedComponents.tsx +++ b/packages/frontend/src/components/feeds/FeedComponents.tsx @@ -99,8 +99,8 @@ export function TweetMedia< E = T extends "video" ? HTMLVideoElement : T extends "audio" - ? HTMLAudioElement - : HTMLImageElement, + ? HTMLAudioElement + : HTMLImageElement, >({ mediaType, className, ...props }: ITweetMedia) { const MediaComponent = mediaType as unknown as FC> | null; return (