Skip to content

Commit

Permalink
🟣 Release 5.3.0
Browse files Browse the repository at this point in the history
Merge pull request #6370 from ikprk/release/5.3.0
  • Loading branch information
ikprk authored Jun 4, 2024
2 parents 4f1e4d6 + a2eabf8 commit 025447f
Show file tree
Hide file tree
Showing 53 changed files with 1,026 additions and 1,633 deletions.
17 changes: 17 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,23 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## [5.3.0] - 2024-06-04

### Added

- Optimistic video updates

### Fixed

- Portfolio table actions
- Show correct potential revenue share on portfolio
- Small UI fixes

### Changed

- Make rewards drawers initially collapsed
- Seperate marketplace into 2 pages

## [5.2.3] - 2024-05-24

### Added
Expand Down
2 changes: 1 addition & 1 deletion packages/atlas/package.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
{
"name": "@joystream/atlas",
"description": "UI for consuming Joystream - a user governed video platform",
"version": "5.2.3",
"version": "5.3.0",
"license": "GPL-3.0",
"scripts": {
"start": "vite",
Expand Down
18 changes: 17 additions & 1 deletion packages/atlas/src/api/client/cache.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { FieldPolicy, FieldReadFunction } from '@apollo/client/cache/inmemory/po
import { offsetLimitPagination, relayStylePagination } from '@apollo/client/utilities'
import { parseISO } from 'date-fns'

import { QueryCommentReactionsConnectionArgs } from '../../../../atlas-meta-server/src/api/__generated__/sdk'
import {
Query,
QueryChannelsConnectionArgs,
Expand Down Expand Up @@ -119,7 +120,19 @@ const getCommentKeyArgs = (
const parentCommentId = args?.where?.parentComment?.id_eq
const videoId = args?.where?.video?.id_eq ?? ctx.variables?.videoId
const orderBy = args?.orderBy || []
return `${parentCommentId}:${videoId}:${orderBy}`
return `parentId-${parentCommentId}-:id-${videoId}-:${orderBy}`
}

const getCommentReactionsKeyArgs = (
args: Partial<QueryCommentReactionsConnectionArgs> | null,
ctx: {
variables?: Record<string, unknown>
}
) => {
const memberId = args?.where?.member?.id_eq
const videoId = args?.where?.video?.id_eq ?? ctx.variables?.videoId
const orderBy = args?.orderBy || []
return `memberId-${memberId}-:videoId-${videoId}-:${orderBy}`
}

const createDateHandler = () => ({
Expand Down Expand Up @@ -216,6 +229,9 @@ const queryCacheFields: CachePolicyFields<keyof Query> = {
return existing?.slice(offset, offset + limit)
},
},
commentReactions: {
...offsetLimitPagination(getCommentReactionsKeyArgs),
},
commentsConnection: relayStylePagination(getCommentKeyArgs),
channelById: (existing, { toReference, args }) => {
return (
Expand Down
16 changes: 15 additions & 1 deletion packages/atlas/src/api/client/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,20 @@ import { GraphQLWsLink } from '@apollo/client/link/subscriptions'
import { getMainDefinition } from '@apollo/client/utilities'
import { createClient } from 'graphql-ws'

import { ORION_GRAPHQL_URL, QUERY_NODE_GRAPHQL_SUBSCRIPTION_URL } from '@/config/env'
import {
FAUCET_URL,
ORION_AUTH_URL,
ORION_GRAPHQL_URL,
QUERY_NODE_GRAPHQL_SUBSCRIPTION_URL,
YPP_FAUCET_URL,
} from '@/config/env'
import { useUserLocationStore } from '@/providers/userLocation'
import { UserEventsLogger } from '@/utils/logs'

import { cache } from './cache'

const followedRequests = [YPP_FAUCET_URL, ORION_GRAPHQL_URL, ORION_AUTH_URL, FAUCET_URL]

const initializePerformanceObserver = () => {
try {
const observer = new PerformanceObserver((list) => {
Expand All @@ -17,6 +25,12 @@ const initializePerformanceObserver = () => {
const queryString = entry.name.split('?')?.[1]
const params = new URLSearchParams(queryString)
const queryType = params.get('queryName')

// Only follow requests to Atlas infra
if (!queryType && !followedRequests.some((allowedUrl) => entry.name.includes(allowedUrl))) {
return
}

UserEventsLogger.logUserEvent('request-response-time', {
requestName: queryType ?? entry.name,
timeToComplete: entry.duration,
Expand Down
12 changes: 9 additions & 3 deletions packages/atlas/src/api/hooks/comments.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ export const useComment = (
}
}

export type UserCommentReactions = Record<string, number[]>
export type UserCommentReactions = Record<string, { reactionId: number; reactionServerId: string }[]>
export const useUserCommentsReactions = (videoId?: string | null, memberId?: string | null) => {
const { data } = useGetUserCommentsReactionsQuery({
variables: {
Expand All @@ -42,9 +42,15 @@ export const useUserCommentsReactions = (videoId?: string | null, memberId?: str

return useMemo(
() => ({
userReactions: data?.commentReactions.reduce<Record<string, number[]>>((acc, item) => {
userReactions: data?.commentReactions.reduce<UserCommentReactions>((acc, item) => {
if (item) {
acc[item.comment.id] = [...(acc[item.comment.id] ? acc[item.comment.id] : []), item.reactionId]
acc[item.comment.id] = [
...(acc[item.comment.id] ? acc[item.comment.id] : []),
{
reactionId: item.reactionId,
reactionServerId: item.id,
},
]
}
return acc
}, {}),
Expand Down
38 changes: 38 additions & 0 deletions packages/atlas/src/api/hooks/useCommentSectionComments.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import { QueryHookOptions } from '@apollo/client'

import { UNCONFIRMED } from '@/hooks/useOptimisticActions'
import { createLookup } from '@/utils/data'

import {
GetUserCommentsAndVideoCommentsConnectionQuery,
GetUserCommentsAndVideoCommentsConnectionQueryVariables,
useGetUserCommentsAndVideoCommentsConnectionQuery,
} from '../queries/__generated__/comments.generated'

export const useCommentSectionComments = (
variables?: GetUserCommentsAndVideoCommentsConnectionQueryVariables,
opts?: QueryHookOptions<
GetUserCommentsAndVideoCommentsConnectionQuery,
GetUserCommentsAndVideoCommentsConnectionQueryVariables
>
) => {
const { data, loading, ...rest } = useGetUserCommentsAndVideoCommentsConnectionQuery({ ...opts, variables })
const userComments = data?.userComments
const userCommentLookup = data?.userComments && createLookup(data?.userComments)
const unconfirmedComments = data?.videoCommentsConnection.edges
.map((edge) => edge.node)
.filter((node) => node.id.includes(UNCONFIRMED))
const unconfirmedCommentLookup = unconfirmedComments && createLookup(unconfirmedComments)

const videoComments = data?.videoCommentsConnection?.edges
.map((edge) => edge.node)
.filter((comment) => userCommentLookup && !userCommentLookup[comment.id] && !unconfirmedCommentLookup?.[comment.id])

return {
userComments,
comments: data ? [...(unconfirmedComments || []), ...(userComments || []), ...(videoComments || [])] : undefined,
loading: loading,
pageInfo: data?.videoCommentsConnection?.pageInfo,
...rest,
}
}

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions packages/atlas/src/api/queries/comments.graphql
Original file line number Diff line number Diff line change
Expand Up @@ -84,6 +84,7 @@ query GetUserCommentsAndVideoCommentsConnection(
# CHANGE: ID is now `String`
query GetUserCommentsReactions($memberId: String!, $videoId: String!) {
commentReactions(where: { member: { id_eq: $memberId }, video: { id_eq: $videoId } }, limit: 1000) {
id
reactionId
comment {
# CHANGE: `commentId` no longer exists, use `comment.id`
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,11 @@ export const KebabMenuIconButton = styled(Button)<{ isActive: boolean }>`
}
`

export const CommentWrapper = styled.div<{ shouldShowKebabButton: boolean }>`
export const CommentWrapper = styled.div<{ shouldShowKebabButton: boolean; isUnconfirmed?: boolean }>`
display: grid;
gap: ${sizes(3)};
align-items: start;
opacity: ${(props) => (props.isUnconfirmed ? '0.8' : 'unset')};
/* comment content, kebab button */
grid-template-columns: 1fr auto;
Expand Down
75 changes: 47 additions & 28 deletions packages/atlas/src/components/_comments/Comment/Comment.tsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import BN from 'bn.js'
import { Dispatch, FC, SetStateAction, memo, useCallback, useRef, useState } from 'react'

import { useComment } from '@/api/hooks/comments'
import { UserCommentReactions, useComment } from '@/api/hooks/comments'
import { CommentStatus } from '@/api/queries/__generated__/baseTypes.generated'
import { CommentFieldsFragment, FullVideoFieldsFragment } from '@/api/queries/__generated__/fragments.generated'
import { DialogModal } from '@/components/_overlays/DialogModal'
Expand All @@ -25,7 +25,7 @@ import { CommentRowProps } from '../CommentRow'
export type CommentProps = {
commentId?: string
video?: FullVideoFieldsFragment | null
userReactions?: number[]
userReactions?: UserCommentReactions[string]
isReplyable?: boolean
setHighlightedCommentId?: Dispatch<SetStateAction<string | null>>
setRepliesOpen?: Dispatch<SetStateAction<boolean>>
Expand Down Expand Up @@ -102,8 +102,10 @@ export const Comment: FC<CommentProps> = memo(
closeModal()
isChannelOwner
? await moderateComment(comment.id, video?.channel.id, comment.author.handle, video?.id)
: await deleteComment(comment.id, video?.title || '', video?.id)
setIsCommentProcessing(false)
: await deleteComment(comment.id, video?.title || '', video?.id, {
onUnconfirmed: () => setIsCommentProcessing(false),
onTxSign: () => setIsCommentProcessing(false),
})
},
},
secondaryButton: {
Expand Down Expand Up @@ -155,27 +157,25 @@ export const Comment: FC<CommentProps> = memo(
}

setEditCommentInputIsProcessing(true)
const success = await updateComment({
await updateComment({
videoId: video.id,
commentBody: editCommentInputText ?? '',
commentId: comment.id,
videoTitle: video.title,
optimisticOpts: {
onTxSign: () => {
setEditCommentInputIsProcessing(false)
setEditCommentInputText('')
setHighlightedCommentId?.(comment?.id ?? null)
setIsEditingComment(false)
},
onUnconfirmed: () => {
setEditCommentInputIsProcessing(false)
setEditCommentInputText('')
setIsEditingComment(false)
},
},
})
setEditCommentInputIsProcessing(false)

if (success) {
setEditCommentInputText('')
setHighlightedCommentId?.(comment?.id ?? null)
setIsEditingComment(false)
}
}
const handleCommentReaction = async (commentId: string, reactionId: CommentReaction) => {
setProcessingReactionsIds((previous) => [...previous, reactionId])
const fee =
reactionFee ||
(await getReactToVideoCommentFee(memberId && comment?.id ? [memberId, comment.id, reactionId] : undefined))
await reactToComment(commentId, video?.id || '', reactionId, comment?.author.handle || '', fee)
setProcessingReactionsIds((previous) => previous.filter((r) => r !== reactionId))
}

const handleOnBoardingPopoverOpen = async (reactionId: number) => {
Expand All @@ -190,19 +190,23 @@ export const Comment: FC<CommentProps> = memo(
}

setReplyCommentInputIsProcessing(true)
const newCommentId = await addComment({
await addComment({
videoId: video.id,
commentBody: replyCommentInputText,
parentCommentId: comment.id,
videoTitle: video.title,
commentAuthorHandle: comment.author.handle,
optimisticOpts: {
onTxSign: (newCommentId) => {
setReplyCommentInputIsProcessing(false)
setReplyCommentInputText('')
setHighlightedCommentId?.(newCommentId || null)
onReplyPosted?.(newCommentId || '')
setRepliesOpen?.(true)
setReplyInputOpen(false)
},
},
})
setReplyCommentInputIsProcessing(false)
setReplyCommentInputText('')
setHighlightedCommentId?.(newCommentId || null)
onReplyPosted?.(newCommentId || '')
setRepliesOpen?.(true)
setReplyInputOpen(false)
}

const handleReplyClick = () => {
Expand Down Expand Up @@ -250,13 +254,28 @@ export const Comment: FC<CommentProps> = memo(
const reactions =
(comment &&
getCommentReactions({
userReactionsIds: userReactions,
userReactionsIds: userReactions?.map((uR) => uR.reactionId),
reactionsCount: comment.reactionsCountByReactionId || [],
processingReactionsIds,
deleted: commentType === 'deleted',
})) ||
undefined

const handleCommentReaction = async (commentId: string, reactionId: CommentReaction) => {
setProcessingReactionsIds((previous) => [...previous, reactionId])
const fee =
reactionFee ||
(await getReactToVideoCommentFee(memberId && comment?.id ? [memberId, comment.id, reactionId] : undefined))
await reactToComment(commentId, video?.id || '', reactionId, comment?.author.handle || '', fee, {
prevReactionServerId:
userReactions?.find((reaction) => reaction.reactionId === reactionId)?.reactionServerId ?? '',
videoId: video?.id ?? '',
onUnconfirmedComment: () => setProcessingReactionsIds((previous) => previous.filter((r) => r !== reactionId)),
onTxSign: () => setProcessingReactionsIds((previous) => previous.filter((r) => r !== reactionId)),
})
setProcessingReactionsIds((previous) => previous.filter((r) => r !== reactionId))
}

if (isEditingComment) {
return (
<CommentInput
Expand Down
Loading

0 comments on commit 025447f

Please sign in to comment.