Spaces:
Running
on
CPU Upgrade
Running
on
CPU Upgrade
Commit
•
139ef57
1
Parent(s):
b6060f3
add number formatting
Browse files- src/app/interface/channel-card/index.tsx +3 -2
- src/app/interface/collection-card/index.tsx +2 -1
- src/app/interface/like-button/generic.tsx +3 -2
- src/app/interface/top-header/index.tsx +6 -3
- src/app/interface/track-card/index.tsx +2 -1
- src/app/interface/video-card/index.tsx +2 -1
- src/app/views/public-video-view/index.tsx +6 -2
- src/lib/formatLargeNumber.ts +14 -0
src/app/interface/channel-card/index.tsx
CHANGED
@@ -7,6 +7,7 @@ import { cn } from "@/lib/utils"
|
|
7 |
import { ChannelInfo } from "@/types"
|
8 |
import { isCertifiedUser } from "@/app/certification"
|
9 |
import { DefaultAvatar } from "../default-avatar"
|
|
|
10 |
|
11 |
export function ChannelCard({
|
12 |
channel,
|
@@ -103,9 +104,9 @@ export function ChannelCard({
|
|
103 |
{isCertifiedUser(channel.datasetUser) ? <div className="text-xs text-neutral-400"><RiCheckboxCircleFill className="" /></div> : null}
|
104 |
</div>}
|
105 |
{!isCreateButton && <div className="flex flex-row items-center justify-center text-neutral-400">
|
106 |
-
<div className="text-center text-xs">{0} videos</div>
|
107 |
<div className="px-1">-</div>
|
108 |
-
<div className="text-center text-xs">{channel.likes} likes</div>
|
109 |
</div>}
|
110 |
</div>
|
111 |
</div>
|
|
|
7 |
import { ChannelInfo } from "@/types"
|
8 |
import { isCertifiedUser } from "@/app/certification"
|
9 |
import { DefaultAvatar } from "../default-avatar"
|
10 |
+
import { formatLargeNumber } from "@/lib/formatLargeNumber"
|
11 |
|
12 |
export function ChannelCard({
|
13 |
channel,
|
|
|
104 |
{isCertifiedUser(channel.datasetUser) ? <div className="text-xs text-neutral-400"><RiCheckboxCircleFill className="" /></div> : null}
|
105 |
</div>}
|
106 |
{!isCreateButton && <div className="flex flex-row items-center justify-center text-neutral-400">
|
107 |
+
<div className="text-center text-xs">{formatLargeNumber(0)} videos</div>
|
108 |
<div className="px-1">-</div>
|
109 |
+
<div className="text-center text-xs">{formatLargeNumber(channel.likes)} likes</div>
|
110 |
</div>}
|
111 |
</div>
|
112 |
</div>
|
src/app/interface/collection-card/index.tsx
CHANGED
@@ -11,6 +11,7 @@ import { formatTimeAgo } from "@/lib/formatTimeAgo"
|
|
11 |
import { isCertifiedUser } from "@/app/certification"
|
12 |
import { transparentImage } from "@/lib/transparentImage"
|
13 |
import { DefaultAvatar } from "../default-avatar"
|
|
|
14 |
|
15 |
export function CollectionCard({
|
16 |
collection,
|
@@ -162,7 +163,7 @@ export function CollectionCard({
|
|
162 |
isCompact ? `text-2xs lg:text-xs` : `text-sm`,
|
163 |
`space-x-1`
|
164 |
)}>
|
165 |
-
<div>{collection.numberOfViews} views</div>
|
166 |
<div className="font-semibold scale-125">·</div>
|
167 |
<div>{formatTimeAgo(collection.updatedAt)}</div>
|
168 |
</div>
|
|
|
11 |
import { isCertifiedUser } from "@/app/certification"
|
12 |
import { transparentImage } from "@/lib/transparentImage"
|
13 |
import { DefaultAvatar } from "../default-avatar"
|
14 |
+
import { formatLargeNumber } from "@/lib/formatLargeNumber"
|
15 |
|
16 |
export function CollectionCard({
|
17 |
collection,
|
|
|
163 |
isCompact ? `text-2xs lg:text-xs` : `text-sm`,
|
164 |
`space-x-1`
|
165 |
)}>
|
166 |
+
<div>{formatLargeNumber(collection.numberOfViews)} views</div>
|
167 |
<div className="font-semibold scale-125">·</div>
|
168 |
<div>{formatTimeAgo(collection.updatedAt)}</div>
|
169 |
</div>
|
src/app/interface/like-button/generic.tsx
CHANGED
@@ -4,6 +4,7 @@ import { RiThumbDownLine } from "react-icons/ri"
|
|
4 |
import { RiThumbDownFill } from "react-icons/ri"
|
5 |
|
6 |
import { cn } from "@/lib/utils"
|
|
|
7 |
|
8 |
export const likeButtonClassName = cn(
|
9 |
`flex flex-row`,
|
@@ -58,7 +59,7 @@ export function GenericLikeButton({
|
|
58 |
<div>{
|
59 |
isLikedByUser ? <RiThumbUpFill /> : <RiThumbUpLine />
|
60 |
}</div>
|
61 |
-
<div>{Math.max(0, numberOfLikes)}</div>
|
62 |
</div>
|
63 |
<div className={cn(
|
64 |
`flex flex-row items-center justify-center`,
|
@@ -76,7 +77,7 @@ export function GenericLikeButton({
|
|
76 |
<div>{
|
77 |
isDislikedByUser ? <RiThumbDownFill /> : <RiThumbDownLine />
|
78 |
}</div>
|
79 |
-
<div>{Math.max(0, numberOfDislikes)}</div>
|
80 |
</div>
|
81 |
</div>
|
82 |
)
|
|
|
4 |
import { RiThumbDownFill } from "react-icons/ri"
|
5 |
|
6 |
import { cn } from "@/lib/utils"
|
7 |
+
import { formatLargeNumber } from "@/lib/formatLargeNumber"
|
8 |
|
9 |
export const likeButtonClassName = cn(
|
10 |
`flex flex-row`,
|
|
|
59 |
<div>{
|
60 |
isLikedByUser ? <RiThumbUpFill /> : <RiThumbUpLine />
|
61 |
}</div>
|
62 |
+
<div>{formatLargeNumber(Math.max(0, numberOfLikes))}</div>
|
63 |
</div>
|
64 |
<div className={cn(
|
65 |
`flex flex-row items-center justify-center`,
|
|
|
77 |
<div>{
|
78 |
isDislikedByUser ? <RiThumbDownFill /> : <RiThumbDownLine />
|
79 |
}</div>
|
80 |
+
<div>{formatLargeNumber(Math.max(0, numberOfDislikes))}</div>
|
81 |
</div>
|
82 |
</div>
|
83 |
)
|
src/app/interface/top-header/index.tsx
CHANGED
@@ -13,6 +13,7 @@ const pathway = Pathway_Gothic_One({
|
|
13 |
import { useStore } from "@/app/state/useStore"
|
14 |
import { cn } from "@/lib/utils"
|
15 |
import { getTags } from '@/app/server/actions/ai-tube-hf/getTags'
|
|
|
16 |
|
17 |
export function TopHeader() {
|
18 |
const [_pending, startTransition] = useTransition()
|
@@ -95,9 +96,11 @@ export function TopHeader() {
|
|
95 |
)} />
|
96 |
</div>
|
97 |
</div>
|
98 |
-
<
|
99 |
-
|
100 |
-
|
|
|
|
|
101 |
</div>
|
102 |
</div>
|
103 |
<div className={cn(
|
|
|
13 |
import { useStore } from "@/app/state/useStore"
|
14 |
import { cn } from "@/lib/utils"
|
15 |
import { getTags } from '@/app/server/actions/ai-tube-hf/getTags'
|
16 |
+
import Link from 'next/link'
|
17 |
|
18 |
export function TopHeader() {
|
19 |
const [_pending, startTransition] = useTransition()
|
|
|
96 |
)} />
|
97 |
</div>
|
98 |
</div>
|
99 |
+
<Link href="/">
|
100 |
+
<div className="font-semibold">
|
101 |
+
{view === "public_music_videos" ? "AiTube Music" : "AiTube"}
|
102 |
+
</div>
|
103 |
+
</Link>
|
104 |
</div>
|
105 |
</div>
|
106 |
<div className={cn(
|
src/app/interface/track-card/index.tsx
CHANGED
@@ -11,6 +11,7 @@ import { formatTimeAgo } from "@/lib/formatTimeAgo"
|
|
11 |
import { isCertifiedUser } from "@/app/certification"
|
12 |
import { transparentImage } from "@/lib/transparentImage"
|
13 |
import { DefaultAvatar } from "../default-avatar"
|
|
|
14 |
|
15 |
export function TrackCard({
|
16 |
media,
|
@@ -228,7 +229,7 @@ export function TrackCard({
|
|
228 |
isCompact ? `text-2xs lg:text-xs` : `text-sm`,
|
229 |
`space-x-1`
|
230 |
)}>
|
231 |
-
<div>{media.numberOfViews} views</div>
|
232 |
<div className="font-semibold scale-125">·</div>
|
233 |
<div>{formatTimeAgo(media.updatedAt)}</div>
|
234 |
</div>}
|
|
|
11 |
import { isCertifiedUser } from "@/app/certification"
|
12 |
import { transparentImage } from "@/lib/transparentImage"
|
13 |
import { DefaultAvatar } from "../default-avatar"
|
14 |
+
import { formatLargeNumber } from "@/lib/formatLargeNumber"
|
15 |
|
16 |
export function TrackCard({
|
17 |
media,
|
|
|
229 |
isCompact ? `text-2xs lg:text-xs` : `text-sm`,
|
230 |
`space-x-1`
|
231 |
)}>
|
232 |
+
<div>{formatLargeNumber(media.numberOfViews)} views</div>
|
233 |
<div className="font-semibold scale-125">·</div>
|
234 |
<div>{formatTimeAgo(media.updatedAt)}</div>
|
235 |
</div>}
|
src/app/interface/video-card/index.tsx
CHANGED
@@ -11,6 +11,7 @@ import { formatTimeAgo } from "@/lib/formatTimeAgo"
|
|
11 |
import { isCertifiedUser } from "@/app/certification"
|
12 |
import { transparentImage } from "@/lib/transparentImage"
|
13 |
import { DefaultAvatar } from "../default-avatar"
|
|
|
14 |
|
15 |
export function VideoCard({
|
16 |
media,
|
@@ -208,7 +209,7 @@ export function VideoCard({
|
|
208 |
isCompact ? `text-2xs lg:text-xs` : `text-sm`,
|
209 |
`space-x-1`
|
210 |
)}>
|
211 |
-
<div>{media.numberOfViews} views</div>
|
212 |
<div className="font-semibold scale-125">·</div>
|
213 |
<div>{formatTimeAgo(media.updatedAt)}</div>
|
214 |
</div>
|
|
|
11 |
import { isCertifiedUser } from "@/app/certification"
|
12 |
import { transparentImage } from "@/lib/transparentImage"
|
13 |
import { DefaultAvatar } from "../default-avatar"
|
14 |
+
import { formatLargeNumber } from "@/lib/formatLargeNumber"
|
15 |
|
16 |
export function VideoCard({
|
17 |
media,
|
|
|
209 |
isCompact ? `text-2xs lg:text-xs` : `text-sm`,
|
210 |
`space-x-1`
|
211 |
)}>
|
212 |
+
<div>{formatLargeNumber(media.numberOfViews)} views</div>
|
213 |
<div className="font-semibold scale-125">·</div>
|
214 |
<div>{formatTimeAgo(media.updatedAt)}</div>
|
215 |
</div>
|
src/app/views/public-video-view/index.tsx
CHANGED
@@ -21,6 +21,7 @@ import { DefaultAvatar } from "@/app/interface/default-avatar"
|
|
21 |
import { LikeButton } from "@/app/interface/like-button"
|
22 |
|
23 |
import { ReportModal } from "../report-modal"
|
|
|
24 |
|
25 |
export function PublicVideoView() {
|
26 |
const [_pending, startTransition] = useTransition()
|
@@ -188,7 +189,10 @@ export function PublicVideoView() {
|
|
188 |
`flex flex-row items-center`,
|
189 |
`text-neutral-400 text-xs font-normal space-x-1`,
|
190 |
)}>
|
191 |
-
<div>
|
|
|
|
|
|
|
192 |
<div></div>
|
193 |
</div>
|
194 |
</a>
|
@@ -271,7 +275,7 @@ export function PublicVideoView() {
|
|
271 |
`text-sm text-zinc-100`,
|
272 |
)}>
|
273 |
<div className="flex flex-row space-x-2 font-medium mb-1">
|
274 |
-
<div>{video.numberOfViews} views</div>
|
275 |
<div>{formatTimeAgo(video.updatedAt).replace("about ", "")}</div>
|
276 |
</div>
|
277 |
<p>{video.description}</p>
|
|
|
21 |
import { LikeButton } from "@/app/interface/like-button"
|
22 |
|
23 |
import { ReportModal } from "../report-modal"
|
24 |
+
import { formatLargeNumber } from "@/lib/formatLargeNumber"
|
25 |
|
26 |
export function PublicVideoView() {
|
27 |
const [_pending, startTransition] = useTransition()
|
|
|
189 |
`flex flex-row items-center`,
|
190 |
`text-neutral-400 text-xs font-normal space-x-1`,
|
191 |
)}>
|
192 |
+
<div>{
|
193 |
+
// TODO implement the follower system
|
194 |
+
formatLargeNumber(0)
|
195 |
+
} followers</div>
|
196 |
<div></div>
|
197 |
</div>
|
198 |
</a>
|
|
|
275 |
`text-sm text-zinc-100`,
|
276 |
)}>
|
277 |
<div className="flex flex-row space-x-2 font-medium mb-1">
|
278 |
+
<div>{formatLargeNumber(video.numberOfViews)} views</div>
|
279 |
<div>{formatTimeAgo(video.updatedAt).replace("about ", "")}</div>
|
280 |
</div>
|
281 |
<p>{video.description}</p>
|
src/lib/formatLargeNumber.ts
ADDED
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
export function formatLargeNumber(num: number): string {
|
2 |
+
if (num < 1000) {
|
3 |
+
return num.toString(); // Display as-is for numbers under 1000
|
4 |
+
} else if (num < 1000000) {
|
5 |
+
// Format for thousands
|
6 |
+
return (num / 1000).toFixed(num < 10000 ? 1 : 0) + "K";
|
7 |
+
} else if (num < 1000000000) {
|
8 |
+
// Format for millions
|
9 |
+
return (num / 1000000).toFixed(num < 10000000 ? 1 : 0) + "M";
|
10 |
+
} else {
|
11 |
+
// Format for billions
|
12 |
+
return (num / 1000000000).toFixed(num < 10000000000 ? 1 : 0) + "B";
|
13 |
+
}
|
14 |
+
}
|