Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ import React from 'react';
import MemesLeaderboardDropCard from '@/components/memes/drops/MemesLeaderboardDropCard';

test.each([
[1, 'desktop-hover:hover:tw-border-[#fbbf24]/40'],
[2, 'desktop-hover:hover:tw-border-[#94a3b8]/40'],
[3, 'desktop-hover:hover:tw-border-[#CD7F32]/40'],
[1, 'desktop-hover:hover:tw-border-yellow-500/20'],
[2, 'desktop-hover:hover:tw-border-iron-400/25'],
[3, 'desktop-hover:hover:tw-border-amber-600/20'],
[4, 'desktop-hover:hover:tw-border-iron-700'],
])('applies border class for rank %i', (rank, expected) => {
const drop = { rank } as any;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -519,7 +519,7 @@ describe("SingleWaveDropTraits", () => {
// Find the metadata item container by looking for the specific class pattern
const { container } = render(<SingleWaveDropTraits drop={drop} />);
const metadataItems = container.querySelectorAll(
".tw-px-2.tw-py-1.tw-rounded-md.tw-bg-iron-800"
String.raw`.tw-px-3.tw-py-1\.5.tw-rounded-md.tw-bg-iron-900`
);
expect(metadataItems.length).toBeGreaterThan(0);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,7 @@ describe('WaveleaderboardSort', () => {
);

const current = screen.getByText('Current Vote');
expect(current.className).toContain('tw-bg-iron-800');
expect(current.className).toContain('tw-bg-white/10');

await user.click(screen.getByText('Projected Vote'));
expect(onSortChange).toHaveBeenCalledWith(
Expand Down
73 changes: 50 additions & 23 deletions components/brain/my-stream/votes/MyStreamWaveMyVote.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import UserCICAndLevel, {
UserCICAndLevelSize,
} from "@/components/user/utils/UserCICAndLevel";
import { SingleWaveDropPosition } from "@/components/waves/drop/SingleWaveDropPosition";
import { cicToType } from "@/helpers/Helpers";
import { cicToType, formatNumberWithCommas } from "@/helpers/Helpers";
import Link from "next/link";
import UserProfileTooltipWrapper from "@/components/utils/tooltip/UserProfileTooltipWrapper";
import { ImageScale } from "@/helpers/image.helpers";
import { Tooltip } from "react-tooltip";

interface MyStreamWaveMyVoteProps {
readonly drop: ExtendedDrop;
Expand Down Expand Up @@ -100,13 +101,11 @@ const MyStreamWaveMyVote: React.FC<MyStreamWaveMyVoteProps> = ({
</div>

<div className="tw-flex tw-flex-col tw-flex-1 tw-min-w-0">
<div className="tw-flex tw-flex-col @md:tw-flex-row @sm:tw-flex-col tw-gap-y-2 tw-gap-x-3">
<div>
{drop.rank && <SingleWaveDropPosition rank={drop.rank} />}
</div>
<div className="tw-flex tw-items-center tw-justify-between tw-gap-x-3">
<h3 className="tw-text-base tw-font-semibold tw-text-iron-50 tw-mb-0">
{drop.title}
</h3>
{drop.rank && <SingleWaveDropPosition rank={drop.rank} />}
</div>
<div className="tw-flex tw-items-center tw-gap-2 tw-mt-4">
<div className="tw-size-6 tw-relative tw-flex-shrink-0 tw-rounded-md tw-overflow-hidden tw-ring-1 tw-ring-white/10 tw-bg-iron-800">
Expand Down Expand Up @@ -144,24 +143,52 @@ const MyStreamWaveMyVote: React.FC<MyStreamWaveMyVoteProps> = ({
<div onClick={(e) => e.stopPropagation()}>
<MyStreamWaveMyVoteVotes drop={drop} />
</div>
<div className="tw-flex tw-items-center tw-gap-1.5">
<svg
xmlns="http://www.w3.org/2000/svg"
fill="none"
aria-hidden="true"
viewBox="0 0 24 24"
strokeWidth="2"
stroke="currentColor"
className="tw-size-4 tw-text-iron-400 tw-flex-shrink-0"
>
<path
strokeLinecap="round"
strokeLinejoin="round"
d="M18 18.72a9.094 9.094 0 0 0 3.741-.479 3 3 0 0 0-4.682-2.72m.94 3.198.001.031c0 .225-.012.447-.037.666A11.944 11.944 0 0 1 12 21c-2.17 0-4.207-.576-5.963-1.584A6.062 6.062 0 0 1 6 18.719m12 0a5.971 5.971 0 0 0-.941-3.197m0 0A5.995 5.995 0 0 0 12 12.75a5.995 5.995 0 0 0-5.058 2.772m0 0a3 3 0 0 0-4.681 2.72 8.986 8.986 0 0 0 3.74.477m.94-3.197a5.971 5.971 0 0 0-.94 3.197M15 6.75a3 3 0 1 1-6 0 3 3 0 0 1 6 0Zm6 3a2.25 2.25 0 1 1-4.5 0 2.25 2.25 0 0 1 4.5 0Zm-13.5 0a2.25 2.25 0 1 1-4.5 0 2.25 2.25 0 0 1 4.5 0Z"
/>
</svg>
<span className="tw-text-sm tw-font-medium tw-text-iron-200">
{drop.raters_count}
<div className="tw-flex tw-items-center tw-gap-2">
<div className="tw-flex tw-items-center -tw-space-x-2">
{drop.top_raters?.slice(0, 3).map((voter) => (
<React.Fragment key={voter.profile.handle}>
<Link
href={`/${voter.profile.handle}`}
onClick={(e) => e.stopPropagation()}
data-tooltip-id={`my-vote-voter-${drop.id}-${voter.profile.handle}`}
>
{voter.profile.pfp ? (
<img
className="tw-w-6 tw-h-6 tw-rounded-md tw-border-2 tw-border-solid tw-border-[#111] tw-bg-iron-800 tw-object-contain"
src={voter.profile.pfp}
alt="Recent voter"
/>
) : (
<div className="tw-w-6 tw-h-6 tw-rounded-md tw-border-2 tw-border-solid tw-border-[#111] tw-bg-iron-800" />
)}
</Link>
<Tooltip
id={`my-vote-voter-${drop.id}-${voter.profile.handle}`}
place="top"
offset={8}
opacity={1}
style={{
padding: "4px 8px",
background: "#37373E",
color: "white",
fontSize: "13px",
fontWeight: 500,
borderRadius: "6px",
boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
zIndex: 99999,
pointerEvents: "none",
}}
>
{voter.profile.handle} - {formatNumberWithCommas(voter.rating)}
</Tooltip>
</React.Fragment>
))}
</div>
<span className="tw-text-white tw-font-bold tw-text-sm">
{formatNumberWithCommas(drop.raters_count)}{" "}
<span className="tw-text-iron-500 tw-font-normal">
{drop.raters_count === 1 ? "voter" : "voters"}
</span>
</span>
</div>
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ const MyStreamWaveMyVoteVotes: React.FC<MyStreamWaveMyVoteVotesProps> = ({
return (
<div className="tw-flex tw-items-center tw-gap-x-1.5">
<span
className={`tw-text-sm tw-font-semibold ${
className={`tw-text-sm tw-font-bold tw-font-mono tw-tracking-tight ${
isPositive ? "tw-text-emerald-500" : "tw-text-rose-500"
}`}
>
Expand Down
8 changes: 4 additions & 4 deletions components/drops/view/utils/DropVoteProgressing.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,9 @@ export default function DropVoteProgressing({
arrowColor = "tw-text-iron-600";
} else {
color = isPositiveProgressing
? "tw-text-emerald-400 tw-bg-emerald-900/40 tw-px-1.5 tw-py-0.5 tw-rounded-md"
: "tw-text-rose-400 tw-bg-rose-900/40 tw-px-1.5 tw-py-0.5 tw-rounded-md";
arrowColor = isPositiveProgressing ? "tw-text-emerald-400" : "tw-text-rose-400";
? "tw-text-emerald-400 tw-bg-emerald-500/10 tw-px-2 tw-py-0.5 tw-rounded tw-border tw-border-solid tw-border-emerald-500/20 tw-font-mono"
: "tw-text-rose-400 tw-bg-rose-500/10 tw-px-2 tw-py-0.5 tw-rounded tw-border tw-border-solid tw-border-rose-500/20 tw-font-mono";
arrowColor = "tw-text-iron-600";
}

return (
Expand All @@ -52,7 +52,7 @@ export default function DropVoteProgressing({
icon={faArrowRight}
className={`tw-flex-shrink-0 tw-size-2.5 ${arrowColor}`}
/>
<span className={`tw-text-xs tw-font-medium ${color}`}>{formatNumberWithCommas(projected)}</span>
<span className={`${subtle ? 'tw-text-xs' : 'tw-text-sm'} tw-font-medium tw-tracking-tight ${color}`}>{formatNumberWithCommas(projected)}</span>
</span>
<Tooltip
id={`drop-vote-progress-${current}-${projected}`}
Expand Down
30 changes: 20 additions & 10 deletions components/memes/drops/MemeDropTrait.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import useIsMobileDevice from "@/hooks/isMobileDevice";
interface MemeDropTraitProps {
readonly label: string;
readonly value: string;
readonly dropId?: string;
}

const convertValue = (value: string) => {
Expand All @@ -24,33 +25,42 @@ const convertValue = (value: string) => {
return value;
};

const MemeDropTrait: React.FC<MemeDropTraitProps> = ({ label, value }) => {
const MemeDropTrait: React.FC<MemeDropTraitProps> = ({ label, value, dropId }) => {
const isMobile = useIsMobileDevice();
const convertedValue = convertValue(value);
const tooltipId = dropId ? `meme-drop-trait-${dropId}-${label}` : `meme-drop-trait-${label}`;

if (label === FIELD_TO_LABEL_MAP.pointsLoki) {
console.log(value, typeof value);
}

return (
<div className="tw-px-2 tw-py-1 tw-rounded-md tw-bg-iron-800 tw-flex tw-flex-col tw-gap-y-1.5">
<span className="tw-text-iron-400 tw-text-xs tw-mr-1.5 tw-font-normal">
{label}:
<div className="tw-bg-iron-900 tw-border tw-border-solid tw-border-white/10 tw-rounded-md tw-px-3 tw-py-1.5 tw-flex tw-flex-col">
<span className="tw-block tw-text-[9px] tw-uppercase tw-tracking-wider tw-text-iron-600 tw-font-bold tw-mb-0.5">
{label}
</span>
<>
<span
className="tw-text-iron-50 tw-text-sm tw-font-medium tw-truncate"
data-tooltip-id={`meme-drop-trait-${label}`}>
<span
className="tw-text-xs tw-text-iron-400 tw-truncate"
data-tooltip-id={tooltipId}>
{convertedValue}
</span>
{!isMobile && (
<Tooltip
id={`meme-drop-trait-${label}`}
id={tooltipId}
place="top"
offset={8}
opacity={1}
style={{
backgroundColor: "#1F2937",
color: "white",
padding: "4px 8px",
background: "#37373E",
color: "white",
fontSize: "13px",
fontWeight: 500,
borderRadius: "6px",
boxShadow: "0 25px 50px -12px rgba(0, 0, 0, 0.25)",
zIndex: 99999,
pointerEvents: "none",
}}>
<span className="tw-text-xs">{convertedValue}</span>
</Tooltip>
Expand Down
8 changes: 5 additions & 3 deletions components/memes/drops/MemeDropTraits.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ const MemeDropTraits: React.FC<MemeDropTraitsProps> = ({ drop }) => {
};

return (
<div className="lg:tw-flex tw-flex-col tw-gap-2 tw-hidden tw-p-4">
<div className="lg:tw-flex tw-flex-col tw-gap-2 tw-hidden">
<div className="tw-grid tw-grid-cols-2 sm:tw-grid-cols-4 tw-gap-2">
{traits.slice(0, 2).map((trait) => (
<MemeDropTrait
Expand All @@ -49,6 +49,7 @@ const MemeDropTraits: React.FC<MemeDropTraitsProps> = ({ drop }) => {
]
}
value={trait.data_value ?? ""}
dropId={drop.id}
/>
))}

Expand All @@ -63,18 +64,19 @@ const MemeDropTraits: React.FC<MemeDropTraitsProps> = ({ drop }) => {
]
}
value={trait.data_value ?? ""}
dropId={drop.id}
/>
))}
<button
onClick={handleShowLess}
className="tw-text-xs tw-text-primary-400 desktop-hover:hover:tw-text-primary-300 tw-transition tw-duration-300 tw-ease-out tw-font-semibold tw-bg-transparent tw-border-0 tw-text-left">
className="tw-text-primary-400 tw-text-xs tw-text-left tw-font-medium desktop-hover:hover:tw-text-primary-300 tw-transition-colors tw-whitespace-nowrap tw-self-end tw-pb-1.5 tw-bg-transparent tw-border-0">
Show less
</button>
</>
) : (
<button
onClick={handleShowAll}
className="tw-text-xs tw-text-primary-400 desktop-hover:hover:tw-text-primary-300 tw-transition tw-duration-300 tw-ease-out tw-font-semibold tw-bg-transparent tw-border-0 tw-text-left">
className="tw-text-primary-400 tw-text-xs tw-text-left tw-font-medium desktop-hover:hover:tw-text-primary-300 tw-transition-colors tw-whitespace-nowrap tw-self-end tw-pb-1.5 tw-bg-transparent tw-border-0">
Show all
</button>
)}
Expand Down
2 changes: 1 addition & 1 deletion components/memes/drops/MemeParticipationDrop.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ export default function MemeParticipationDrop({
<>
<div className="tw-p-4">
<MemeDropArtistInfo drop={drop} />
<div className="tw-flex tw-flex-col tw-mt-2 sm:tw-mt-1.5 sm:tw-ml-[3.25rem]">
<div className="tw-flex tw-flex-col tw-mt-2 sm:tw-mt-1.5 sm:tw-ml-[3.75rem]">
<MemeDropHeader title={title} />
<MemeDropDescription description={description} />
</div>
Expand Down
18 changes: 8 additions & 10 deletions components/memes/drops/MemeWinnerArtistInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -23,9 +23,9 @@ export default function MemeWinnerArtistInfo({
const cicType = cicToType(drop.author?.cic);

return (
<div className="tw-flex tw-items-center tw-gap-x-3">
<div className="tw-flex tw-items-start tw-gap-x-3">
<WaveDropAuthorPfp drop={drop} />
<div className="tw-flex tw-flex-col tw-gap-y-1.5">
<div className="tw-flex tw-flex-col tw-items-start tw-gap-y-2">
<div className="tw-flex tw-items-center tw-gap-x-2">
{!!drop.author?.level && (
<UserCICAndLevel
Expand All @@ -34,7 +34,7 @@ export default function MemeWinnerArtistInfo({
size={UserCICAndLevelSize.SMALL}
/>
)}
<p className="tw-text-md tw-mb-0 tw-leading-none tw-font-semibold tw-hidden sm:tw-block">
<p className="tw-text-md tw-mb-0 tw-leading-none tw-font-semibold">
{drop.author?.handle ? (
<UserProfileTooltipWrapper user={drop.author.handle ?? drop.author.id}>
<Link
Expand All @@ -48,22 +48,20 @@ export default function MemeWinnerArtistInfo({
) : (
<Link
onClick={(e) => e.stopPropagation()}
href={`/${drop.author?.handle}`}
href={`/${drop.author?.handle ?? drop.author?.id}`}
className="tw-no-underline desktop-hover:hover:tw-underline tw-text-iron-200 desktop-hover:hover:tw-text-opacity-80 tw-transition tw-duration-300 tw-ease-out"
>
{drop.author?.handle}
{drop.author?.handle ?? drop.author?.id}
</Link>
)}
</p>

<div className="tw-size-[3px] tw-bg-iron-600 tw-rounded-full tw-flex-shrink-0 tw-hidden sm:tw-block"></div>
<p className="tw-text-md tw-mb-0 tw-whitespace-nowrap tw-font-normal tw-leading-none tw-text-iron-500">
<div className="tw-size-[3px] tw-bg-iron-600 tw-rounded-full tw-flex-shrink-0"></div>
<p className="tw-text-xs tw-mb-0 tw-whitespace-nowrap tw-font-normal tw-leading-none tw-text-iron-500">
{getTimeAgoShort(drop.created_at)}
</p>
<div className="tw-ml-2">
<WinnerDropBadge rank={1} decisionTime={decisionTime ?? null} />
</div>
</div>
<WinnerDropBadge rank={1} decisionTime={decisionTime ?? null} />

{showWaveInfo && drop.wave && (
<Link
Expand Down
32 changes: 17 additions & 15 deletions components/memes/drops/MemeWinnerDrop.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,11 @@
"use client"
"use client";

import React, { useCallback } from "react";
import { ExtendedDrop } from "@/helpers/waves/drop.helpers";
import { DropInteractionParams, DropLocation } from "@/components/waves/drops/Drop";
import {
DropInteractionParams,
DropLocation,
} from "@/components/waves/drops/Drop";
import useIsMobileDevice from "@/hooks/isMobileDevice";
import WaveDropActions from "@/components/waves/drops/WaveDropActions";
import MemeWinnerHeader from "./MemeWinnerHeader";
Expand Down Expand Up @@ -50,10 +53,10 @@ export default function MemeWinnerDrop({

// First place shadow class from DefaultWaveWinnerDrop
const firstPlaceShadow =
"tw-shadow-[inset_1px_0_0_#fbbf24,inset_0_1px_0_rgba(251,191,36,0.2),inset_-1px_0_0_rgba(251,191,36,0.2),inset_0_-1px_0_rgba(251,191,36,0.2)]";
"tw-shadow-[inset_1px_0_0_rgba(251,191,36,0.5),inset_0_1px_0_rgba(251,191,36,0.2),inset_-1px_0_0_rgba(251,191,36,0.2),inset_0_-1px_0_rgba(251,191,36,0.2)]";

return (
<div className="tw-w-full">
<div className="tw-w-full tw-mb-3">
<div
className={`tw-w-full ${
location === DropLocation.WAVE ? "tw-px-4 tw-py-1" : ""
Expand All @@ -73,33 +76,32 @@ export default function MemeWinnerDrop({
onQuote={handleOnQuote}
>
<>
<div className="tw-p-4">
<div className="tw-flex tw-flex-col tw-gap-4">
<MemeWinnerArtistInfo drop={drop} />
</div>
<div className="tw-flex tw-flex-col tw-mt-2 sm:tw-mt-1.5 sm:tw-ml-[3.25rem]">
<div className="tw-p-4 tw-pb-3 tw-border-b tw-border-solid tw-border-x-0 tw-border-t-0 tw-border-white/5 tw-bg-iron-900/30">
<MemeWinnerArtistInfo drop={drop} />
</div>

<div className="tw-px-4 tw-pt-4 tw-pb-4">
<div className="tw-space-y-1">
<MemeWinnerHeader title={title} />
<MemeWinnerDescription description={description} />
</div>
</div>

{artworkMedia && (
<div className={`tw-flex tw-justify-center tw-mx-[1px] tw-h-96 ${
location === DropLocation.WAVE ? "tw-bg-iron-800/30" : ""
}`}>
<div className="tw-flex tw-justify-center tw-h-96 tw-mx-0.5 tw-bg-iron-950">
<DropListItemContentMedia
media_mime_type={artworkMedia.mime_type}
media_url={artworkMedia.url}
isCompetitionDrop={true}
/>
</div>
)}


<div className="tw-hidden lg:tw-block tw-p-4 tw-mt-4 tw-border-t tw-border-solid tw-border-x-0 tw-border-b-0 tw-border-white/5 tw-bg-iron-900/30">
<MemeDropTraits drop={drop} />

</div>
</>
</DropMobileMenuHandler>
{/* Actions for desktop */}
{!isMobile && showReplyAndQuote && (
<div className="tw-absolute tw-right-4 tw-top-2">
<WaveDropActions
Expand Down
Loading