From 791e973d5d6b48368af917da289b13dab5af38e8 Mon Sep 17 00:00:00 2001 From: BackSH00TER <18689469+BackSH00TER@users.noreply.github.com> Date: Thu, 13 Jul 2023 18:03:00 -0700 Subject: [PATCH] broadcast twitter add / remove like and notify --- apps/game/client/cl_twitter.ts | 8 +++ apps/game/server/twitter/twitter.service.ts | 2 + .../apps/twitter/hooks/useTwitterActions.ts | 23 ++++++++- .../apps/twitter/hooks/useTwitterService.ts | 49 ++++++++++++++++--- typings/twitter.ts | 1 + 5 files changed, 73 insertions(+), 10 deletions(-) diff --git a/apps/game/client/cl_twitter.ts b/apps/game/client/cl_twitter.ts index 35e685f2f..fb1146b27 100644 --- a/apps/game/client/cl_twitter.ts +++ b/apps/game/client/cl_twitter.ts @@ -16,3 +16,11 @@ RegisterNuiProxy(TwitterEvents.RETWEET); onNet(TwitterEvents.CREATE_TWEET_BROADCAST, (tweet: any) => { sendTwitterMessage(TwitterEvents.CREATE_TWEET_BROADCAST, tweet); }); + +onNet(TwitterEvents.TWEET_LIKED_BROADCAST, ( + tweetId: number, + isAddLike: boolean, + likedByProfileName: string +) => { + sendTwitterMessage(TwitterEvents.TWEET_LIKED_BROADCAST, {tweetId, isAddLike, likedByProfileName}); +}); diff --git a/apps/game/server/twitter/twitter.service.ts b/apps/game/server/twitter/twitter.service.ts index 0a26680ea..2fb7ffc7b 100644 --- a/apps/game/server/twitter/twitter.service.ts +++ b/apps/game/server/twitter/twitter.service.ts @@ -216,6 +216,7 @@ class _TwitterService { const identifier = PlayerService.getIdentifier(reqObj.source); const profile = await this.twitterDB.getOrCreateProfile(identifier); const likeExists = await this.twitterDB.doesLikeExist(profile.id, reqObj.data.tweetId); + const likedByProfileName = profile.profile_name; if (likeExists) { await this.twitterDB.deleteLike(profile.id, reqObj.data.tweetId); @@ -224,6 +225,7 @@ class _TwitterService { } resp({ status: 'ok' }); + emitNet(TwitterEvents.TWEET_LIKED_BROADCAST, -1, reqObj.data.tweetId, !likeExists, likedByProfileName); } catch (e) { twitterLogger.error(`Like failed, ${e.message}`, { source: reqObj.source, diff --git a/apps/phone/src/apps/twitter/hooks/useTwitterActions.ts b/apps/phone/src/apps/twitter/hooks/useTwitterActions.ts index 12c6135c7..89545717a 100644 --- a/apps/phone/src/apps/twitter/hooks/useTwitterActions.ts +++ b/apps/phone/src/apps/twitter/hooks/useTwitterActions.ts @@ -11,6 +11,7 @@ interface TwitterActionProps { deleteTweet: (tweetId: number) => void; updateLocalProfile: (profile: UpdateProfileProps) => void; localToggleLike: (tweetId: number) => void; + updateTweetLikes: (tweetId: number, isAddLike: boolean) => void; } const getIsTweetsLoading = (snapshot: Snapshot) => @@ -70,6 +71,7 @@ export const useTwitterActions = (): TwitterActionProps => { [setTweets], ); + // Toggles the isLiked field const localToggleLike = useCallback( (tweetId: number) => { setTweets((curVal) => @@ -78,7 +80,6 @@ export const useTwitterActions = (): TwitterActionProps => { return { ...tweet, isLiked: tweet.isLiked ? false : true, - likes: tweet.isLiked ? tweet.likes - 1 : tweet.likes + 1, }; } return tweet; @@ -88,6 +89,23 @@ export const useTwitterActions = (): TwitterActionProps => { [setTweets], ); + // Updates the tweet likes count, adds or subtracts depending on isAddLike + const updateTweetLikes = useCallback((tweetId: number, isAddLike: boolean) => { + setTweets((curVal) => + [...curVal].map((tweet) => { + if (tweet.id === tweetId) { + return { + ...tweet, + likes: isAddLike ? tweet.likes + 1 : tweet.likes - 1, + }; + } + return tweet; + }), + ); + }, + [setTweets], + ); + return { updateTweets, updateFilteredTweets, @@ -95,5 +113,6 @@ export const useTwitterActions = (): TwitterActionProps => { deleteTweet, updateLocalProfile, localToggleLike, + updateTweetLikes, }; -}; +}; \ No newline at end of file diff --git a/apps/phone/src/apps/twitter/hooks/useTwitterService.ts b/apps/phone/src/apps/twitter/hooks/useTwitterService.ts index b95a28f56..024bcb97f 100644 --- a/apps/phone/src/apps/twitter/hooks/useTwitterService.ts +++ b/apps/phone/src/apps/twitter/hooks/useTwitterService.ts @@ -8,7 +8,7 @@ import { Tweet, TwitterEvents } from '@typings/twitter'; import { useTwitterActions } from './useTwitterActions'; import { processBroadcastedTweet, processTweet } from '../utils/tweets'; import { useNotification } from '@os/new-notifications/useNotification'; -import { useLocation, useRouteMatch } from 'react-router-dom'; +import { useLocation } from 'react-router-dom'; /** * Service to handle all NUI <> client interactions. We take @@ -18,10 +18,8 @@ import { useLocation, useRouteMatch } from 'react-router-dom'; * there and have moved that logic here instead. */ -// TODO: Bring back notifications - export const useTwitterService = () => { - const { addTweet } = useTwitterActions(); + const { addTweet, updateTweetLikes } = useTwitterActions(); const [tweets, setTweets] = useTweetsState(); const { enqueueNotification } = useNotification(); const { pathname } = useLocation(); @@ -36,12 +34,25 @@ export const useTwitterService = () => { }; const addNotification = useCallback( - (data: any) => { + (tweet: Tweet) => { enqueueNotification({ appId: 'TWITTER', - content: data.message, + content: tweet.message, + notisId: 'npwd:tweetBroadcast', + secondaryTitle: tweet.profile_name, + path: '/twitter', + playSound: true, + }); + }, + [enqueueNotification], + ); + + const addLikedTweetNotification = useCallback( + (likedByProfileName: string) => { + enqueueNotification({ + appId: 'TWITTER', + content: `@${likedByProfileName} liked your tweet!`, notisId: 'npwd:tweetBroadcast', - secondaryTitle: data.profile_name, path: '/twitter', }); }, @@ -67,6 +78,28 @@ export const useTwitterService = () => { [addTweet, addNotification, profileContent, profileLoading, setTweets, tweets.length, pathname], ); + const handleTweetLikedBroadcast = useCallback(( + {tweetId, isAddLike, likedByProfileName}: { + tweetId: number, + isAddLike: boolean, + likedByProfileName: string + } + ) => { + updateTweetLikes(tweetId, isAddLike); + + // Only notify when a like is added (dont notify when its removed) + // Dont notify if you are looking at twitter + if (isAddLike && !pathname.includes('/twitter')) { + const likedTweet = tweets.find(tweet => tweet.id == tweetId); + + // Only notify if the user is the owner of the tweet and its not a self like + if (likedTweet.isMine && likedTweet.profile_name !== likedByProfileName) { + addLikedTweetNotification(likedByProfileName); + } + } + }, [addLikedTweetNotification, updateTweetLikes, tweets]); + useNuiEvent(APP_TWITTER, TwitterEvents.FETCH_TWEETS_FILTERED, _setFilteredTweets); useNuiEvent(APP_TWITTER, TwitterEvents.CREATE_TWEET_BROADCAST, handleTweetBroadcast); -}; + useNuiEvent(APP_TWITTER, TwitterEvents.TWEET_LIKED_BROADCAST, handleTweetLikedBroadcast); +}; \ No newline at end of file diff --git a/typings/twitter.ts b/typings/twitter.ts index a31b0749d..be107c5b4 100644 --- a/typings/twitter.ts +++ b/typings/twitter.ts @@ -83,4 +83,5 @@ export enum TwitterEvents { TOGGLE_LIKE = 'npwd:toggleLike', RETWEET = 'npwd:retweet', REPORT = 'npwd:reportTweet', + TWEET_LIKED_BROADCAST = 'npwd:tweetLikedBroadcast', }