Skip to content

Commit

Permalink
Merge pull request #394 from dappforce/deploy/batch-view
Browse files Browse the repository at this point in the history
Add batch post view
  • Loading branch information
teodorus-nathaniel authored Mar 28, 2024
2 parents 9f455f3 + 30892fa commit 3e0a850
Show file tree
Hide file tree
Showing 7 changed files with 178 additions and 151 deletions.
70 changes: 70 additions & 0 deletions src/components/posts/PostViewSubmitter.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
import { useEffect } from 'react'
import { POST_VIEW_DURATION } from 'src/config/constants'
import { LocalStorage } from 'src/utils/storage'
import { useMyAddress } from '../auth/MyAccountsContext'
import { addPostViews } from '../utils/datahub/post-view'

const postViewStorage = new LocalStorage(() => 'post-view')
function addPostViewsToStorage(postId: string) {
const string = postViewStorage.get() ?? ''
postViewStorage.set(`${string},${postId}`)
}
function getPostViewsFromStorage() {
const postViewsString = postViewStorage.get()
if (!postViewsString) return []
const postViews = postViewsString.split(',').filter(Boolean)
if (!Array.isArray(postViews)) return []

const filteredIds = new Set<string>(postViews)
return Array.from(filteredIds)
}

export function usePostViewTracker(postId: string, sharedPostId?: string, enabled?: boolean) {
useEffect(() => {
if (!enabled) return

const timeoutId = setTimeout(async () => {
addPostViewsToStorage(postId)
if (sharedPostId) addPostViewsToStorage(sharedPostId)
}, POST_VIEW_DURATION)

return () => {
clearTimeout(timeoutId)
}
}, [enabled])
}

const BATCH_TIMEOUT = 10_000
export default function PostViewSubmitter() {
const myAddress = useMyAddress()

useEffect(() => {
if (!myAddress) return

console.log('masuk?')
const intervalId = setInterval(async () => {
try {
const postViews = getPostViewsFromStorage()
console.log('postviews?', postViews)
if (!postViews.length) return

postViewStorage.remove()
await addPostViews({
args: {
views: Array.from(postViews).map(value => ({
duration: POST_VIEW_DURATION,
viewerId: myAddress,
postPersistentId: value,
})),
},
})
} catch {}
}, BATCH_TIMEOUT)

return () => {
clearTimeout(intervalId)
}
}, [myAddress])

return null
}
19 changes: 2 additions & 17 deletions src/components/posts/view-post/PostPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,10 @@ import SpaceCard from 'src/components/spaces/SpaceCard'
import { postUrl } from 'src/components/urls'
import { Loading, useIsVisible } from 'src/components/utils'
import DfCard from 'src/components/utils/cards/DfCard'
import { addPostView } from 'src/components/utils/datahub/post-view'
import NoData from 'src/components/utils/EmptyList'
import { return404 } from 'src/components/utils/next'
import Segment from 'src/components/utils/Segment'
import config from 'src/config'
import { POST_VIEW_DURATION } from 'src/config/constants'
import { appId } from 'src/config/env'
import { resolveIpfsUrl } from 'src/ipfs'
import { getInitialPropsWithRedux, NextContextWithRedux } from 'src/rtk/app'
Expand All @@ -41,6 +39,7 @@ import Section from '../../utils/Section'
import ViewTags from '../../utils/ViewTags'
import Embed, { getEmbedLinkType, getGleevVideoId, getYoutubeVideoId } from '../embed/Embed'
import { StatsPanel } from '../PostStats'
import { usePostViewTracker } from '../PostViewSubmitter'
import ViewPostLink from '../ViewPostLink'
import {
HiddenPostAlert,
Expand Down Expand Up @@ -265,21 +264,7 @@ const InnerPostPage: NextPage<PostDetailsProps> = props => {

function PostViewChecker({ postId }: { postId: string }) {
const myAddress = useMyAddress()
useEffect(() => {
const timeoutId = setTimeout(async () => {
try {
await addPostView({
args: { viewerId: myAddress, duration: POST_VIEW_DURATION, postPersistentId: postId },
})
} catch (err) {
console.error('Failed to add view', err)
}
}, POST_VIEW_DURATION)

return () => {
clearTimeout(timeoutId)
}
}, [postId])
usePostViewTracker(postId, undefined, !!myAddress)
return null
}

Expand Down
38 changes: 3 additions & 35 deletions src/components/posts/view-post/PostPreview.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,8 @@
import { newLogger } from '@subsocial/utils'
import { useRouter } from 'next/router'
import { useEffect } from 'react'
import { useInView } from 'react-intersection-observer'
import { useMyAddress } from 'src/components/auth/MyAccountsContext'
import { addPostView } from 'src/components/utils/datahub/post-view'
import { Segment } from 'src/components/utils/Segment'
import { POST_VIEW_DURATION } from 'src/config/constants'
import { useIsPostBlocked } from 'src/rtk/features/moderation/hooks'
import { asSharedPostStruct, PostWithAllDetails, PostWithSomeDetails, SpaceData } from 'src/types'
import {
Expand All @@ -15,6 +12,7 @@ import {
SharedPreview,
useIsUnlistedPost,
} from '.'
import { usePostViewTracker } from '../PostViewSubmitter'
import PostNotEnoughMinStakeAlert from './helpers'

const log = newLogger('ViewPost')
Expand Down Expand Up @@ -61,38 +59,8 @@ export function PostPreview(props: PreviewProps) {
const { isBlocked } = useIsPostBlocked(post)

const { inView, ref } = useInView()
useEffect(() => {
if (!inView || !myAddress) return

const timeoutId = setTimeout(async () => {
try {
const operations = [
addPostView({
args: { viewerId: myAddress, duration: POST_VIEW_DURATION, postPersistentId: post.id },
}),
]
if (post.isSharedPost) {
const originalPostId = asSharedPostStruct(post).originalPostId
operations.push(
addPostView({
args: {
viewerId: myAddress,
duration: POST_VIEW_DURATION,
postPersistentId: originalPostId,
},
}),
)
}
await Promise.all(operations)
} catch (err) {
console.error('Failed to add view', err)
}
}, POST_VIEW_DURATION)

return () => {
clearTimeout(timeoutId)
}
}, [inView, myAddress])
const sharedPostOriginalId = isSharedPost ? asSharedPostStruct(post).originalPostId : undefined
usePostViewTracker(post.id, sharedPostOriginalId, inView && !!myAddress)

if (isUnlisted || isHiddenChatRoom || isBlocked) return null

Expand Down
6 changes: 3 additions & 3 deletions src/components/utils/datahub/post-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,11 @@ export async function getPostsViewCount(postIds: string[]): Promise<PostViewCoun
}

// MUTATIONS
export async function addPostView(
params: Omit<DatahubParams<SocialCallDataArgs<'synth_add_post_view'>>, 'address'>,
export async function addPostViews(
params: Omit<DatahubParams<SocialCallDataArgs<'synth_add_post_views_batch'>>, 'address'>,
) {
// `signer` is using backend signer address
const input = createSocialDataEventPayload(socialCallName.synth_add_post_view, {
const input = createSocialDataEventPayload(socialCallName.synth_add_post_views_batch, {
...params,
address: '',
})
Expand Down
2 changes: 2 additions & 0 deletions src/pages/_app.js
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ import Script from 'next/script'
import { initAllStores } from 'src/stores/registry'
import { ReferralUrlChanger } from 'src/components/referral/ReferralUrlChanger'
import ModerationProvider from 'src/components/posts/ModerationProvider'
import PostViewSubmitter from 'src/components/posts/PostViewSubmitter'

dayjs.extend(relativeTime)
dayjs.extend(localizedFormat)
Expand Down Expand Up @@ -86,6 +87,7 @@ function MyApp(props) {
showSpinner: false,
}}
/>
<PostViewSubmitter />
<Provider store={store}>
{/* <AdBlockModal /> */}
<GoogleAnalytics trackPageViews gaMeasurementId={config.ga.id} />
Expand Down
12 changes: 6 additions & 6 deletions src/server/datahub-queue/post-view.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,9 @@ import { gql } from 'graphql-request'
import { getServerAccount } from '../common'
import { backendSigWrapper, datahubQueueRequest, throwErrorIfNotProcessed } from './utils'

const ADD_POST_VIEW = gql`
mutation AddPostView($args: CreateMutatePostOffChainDataInput!) {
addPostView(args: $args) {
const ADD_POST_VIEW_BATCH = gql`
mutation AddPostViewBatch($args: CreateMutatePostOffChainDataInput!) {
addPostViewsBatch(args: $args) {
processed
message
}
Expand All @@ -22,12 +22,12 @@ export async function addPostView(input: SocialEventDataApiInput) {
input.callData.signer = signerAddress
const signedPayload = await backendSigWrapper(input)
const res = await datahubQueueRequest<{
addPostView: { processed: boolean; message: string | null }
addPostViewsBatch: { processed: boolean; message: string | null }
}>({
document: ADD_POST_VIEW,
document: ADD_POST_VIEW_BATCH,
variables: {
args: signedPayload,
},
})
throwErrorIfNotProcessed(res.addPostView, 'Failed to add post view')
throwErrorIfNotProcessed(res.addPostViewsBatch, 'Failed to add post view')
}
Loading

0 comments on commit 3e0a850

Please sign in to comment.