Skip to content

WIP: Feat/feeds hashtag change indicator#206

Open
paolomolo wants to merge 46 commits intodevelopfrom
feat/feeds-hashtag-change-indicator
Open

WIP: Feat/feeds hashtag change indicator#206
paolomolo wants to merge 46 commits intodevelopfrom
feat/feeds-hashtag-change-indicator

Conversation

@paolomolo
Copy link
Contributor

@paolomolo paolomolo commented Oct 22, 2025

Note

Adds inline hashtag performance badges, introduces an app-wide trade event bus, and updates generated APIs and trading components with null-safety and new endpoints.

  • Social/Feed:
    • Render hashtags via HashtagWithChange to show inline performance badges (24h/7d/30d), using TopicDto.token.performance or fetched data.
    • Pass post context to linkify(...) across FeedItem, ReplyToFeedItem, CommentItem, PostContent, TokenCreated* components.
  • API (generated):
    • Add models: PerformancePeriodDto, TokenPerformanceDto, TopicDto.
    • Change PostDto.topics to TopicDto[]; extend TokenDto with new fields (e.g., create_tx_hash, dao_address, trending_score, performance).
    • New endpoints: DexService.getTokenPriceWithLiquidityAnalysis, PostsService.popular, TokensService.performanceRaw.
  • Trading/DEX:
    • New lightweight event bus (libs/events.ts) and emit trade events from SwapForm.
    • Improve null-safety and reactivity in TokenTradeCard, useTokenTrade, useLiveTokenData, TokenRanking, TokenSaleDetails.
  • Styles:
    • Standardize anchor styling to solid #00ff9d (remove gradient text).
  • Token Detail:
    • Guard AEX-9 totals/FDV with fallbacks; minor data fetching fixes.
  • Misc:
    • Add i18n hook usage in MiniWalletInfo.

Written by Cursor Bugbot for commit df7445e. This will update automatically on new commits. Configure here.

Introduce src/libs/events.ts with onTrade/emitTrade for app-wide trade events.

Used to trigger 24h performance refetch on hashtag indicators.
Fetches trending tags via TrendminerApi and builds TAG->sale_address map.

Auto-refetches every 60s with short stale time.
…refetch

Fetches token performance via TrendminerApi; auto-refetches and refreshes on trade events.

Key: ['token-performance:24h', saleAddress] with 60s interval.
Renders unicode arrow and 24h % next to hashtag if mapped to a trend token.

Tiny inline footprint: ml-1, gap-1, text-[11px] to fit a single line.
Wire linkify to render HashtagWithChange for #tags; keeps link + tiny arrow% badge.

Affects ReplyToFeedItem, FeedItem, PostContent, CommentItem via linkify.
Calls emitTrade with input/output token addresses to refresh dependent UI (e.g., hashtag 24h change).

Hooked in SwapForm post-swap success path.
If tag not in trending tags map, query listTokens(search=tag) and use exact name/symbol match to fetch sale_address for 24h change.

Improves coverage so indicators show for valid tokens not in current trending feed.
If not in trending map and search misses, query getTopicByName(tag) to derive sale_address.

Improves indicator visibility for tags with posts but not trending results.
Try token performance for given address; if missing, resolve canonical token and retry with sale/address.

Addresses cases where endpoint requires sale_address specifically or returns nested payloads.
Map past_24h.current_change_percent or flat current_change_percent to unified shape for hashtag badges.

Ensures badges render regardless of backend response variant.
Prefer /api/tokens/{address}/performance via generated client; fallback to TrendminerApi only if needed.

Improves load time and consistency with generated API.
…ange

Some tokens return only nested percentage as string; parseFloat and map to display value instead of 0.000%.
Try performance for given address, resolved sale_address, and legacy; select non-null with largest |percentage| to avoid 0.000% from wrong address.
…ance

Use token.address over sale_address when resolving hashtag→address to match /api/tokens/{address}/performance.

Should fix 0.000% when sale address didn’t resolve.
Query TokensService.performance with symbol (e.g., FUCK) first, then resolved address; include both in cache key and trade refetch.

Aims to fix 0% when address mapping is off but symbol endpoint works.
Log raw API responses, mapping results, and selected candidate to diagnose 0% display.

Temporary debug for investigation.
Filter out zero percent (insufficient 24h data) so badges only show meaningful price changes.

Remove debug console logs.
When past_24h returns 0 (insufficient data), use all_time.current_change_percent to show real price movement for new tokens.
Replace arrow+percent with rounded pill badge (px-1.5 py-0.5, text-[10px], border).

Green for positive, red for negative; cleaner inline appearance.
Reduce padding (px-1), use font-mono and tracking-tighter for condensed numeric display.
Change hashtag color from var(--neon-teal) to text-white/90 for cleaner appearance.
Show 0% for zero change (no sign), 1 decimal for values >=1, 2-3 for smaller values.
Update hashtags, AENS names, account addresses, and external URLs to use solid green color instead of var(--neon-teal) gradient.
Replace accent gradient with solid green (#00ff9d) in base.scss for all anchor elements and their hover underlines.
Keep the accent gradient in the a::after hover underline while maintaining solid green for link text.
Remove hover:underline classes from HashtagWithChange and linkify utility to prevent double underlines. The global a::after gradient underline will handle hover effects.
Change gap from gap-1 to gap-0.5 in HashtagWithChange component for tighter spacing.
Add relative and inline-block classes to hashtag Link components to properly support the ::after gradient underline on hover.
@netlify
Copy link

netlify bot commented Oct 22, 2025

Deploy Preview for fancy-gelato-7cdad5 ready!

Name Link
🔨 Latest commit df7445e
🔍 Latest deploy log https://app.netlify.com/projects/fancy-gelato-7cdad5/deploys/690cec2342fbcb0008ac29a3
😎 Deploy Preview https://deploy-preview-206--fancy-gelato-7cdad5.netlify.app
📱 Preview on mobile
Toggle QR Code...

QR Code

Use your smartphone camera to open QR code link.

To edit notification comments on pull requests, go to your Netlify project configuration.

@Andreea167
Copy link

Andreea167 commented Oct 23, 2025

  1. Should the percentage always reflect the change in the last 24 hours?
    For example, for this token (https://deploy-preview-206--fancy-gelato-7cdad5.netlify.app/trends/tokens/CRYS
    ), the last transaction was on July 1, but it still shows a +93% increase, which clearly is not from the last 24 hours.

So should we always calculate based on the latest 24 hours, or keep showing the old percentage even if the last trade was months ago? @paolomolo

  1. Also, I think a minus "-" sign for when the price decrees would be nice to add
Screenshot 2025-10-23 at 17 56 28

- Introduced PerformancePeriodDto, TokenPerformanceDto, and TopicDto to improve data structure.
- Updated PostDto to use TopicDto for topics array.
- Enhanced TokenDto with additional fields for better token performance tracking.
- Added a new method in DexService for comprehensive token price analysis.
- Added a method in PostsService to fetch popular posts based on a time window.
…mpatibility

- Introduced performanceRaw method to retrieve token performance data via a new endpoint.
- This method serves as an alias for the existing /performance endpoint, ensuring backward compatibility.
- Enhanced documentation for the new method, including parameter and return type details.
…used queries and integrating post performance data

- Removed unused trending tag and token resolution queries.
- Integrated post performance data to display change percentage for hashtags.
- Updated rendering logic to reflect performance changes directly from post topics.
…g rendering

- Updated linkify function to include an optional post parameter of type PostDto.
- Modified HashtagWithChange component usage to pass post data for enhanced rendering.
…s for improved rendering

- Updated linkify calls in CommentItem, FeedItem, PostContent, ReplyToFeedItem, TokenCreatedActivityItem, and TokenCreatedFeedItem components to include the post parameter.
- This enhancement allows for better rendering of links and hashtags associated with specific posts.
…ing tags

- Deleted the useTokenPerformance and useTrendingTagMap hooks as they were no longer needed.
- This cleanup helps streamline the codebase and reduce unnecessary complexity.
title="24h change"
aria-label={`24h change: ${topic?.token?.performance?.past_30d?.current_change_percent?.toFixed(2)}%`}
>
{topic?.token?.performance?.past_30d?.current_change_percent?.toFixed(2)}%
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Misleading Timeframe Label in HashtagWithChange Component

The HashtagWithChange component uses 30-day performance data but labels it as "24h change" in the title and aria-label, which misleads users about the displayed time period.

Fix in Cursor Fix in Web

@paolomolo paolomolo changed the title Feat/feeds hashtag change indicator WIP: Feat/feeds hashtag change indicator Nov 4, 2025
- Add import for useTranslation from react-i18next

- Fixes ReferenceError that was breaking the user profile page
- Fix Promise.all destructuring where 3 promises were assigned to 2 variables

- Add null checks for aex9Data to prevent runtime errors

- Display 'N/A' when token metadata is unavailable
…mponents

- Update TokenTradeCard, TokenRanking, useLiveTokenData, useTokenTrade, and TokenSaleDetails to handle null or undefined token values.
- Ensure components return null when token is not available to prevent runtime errors.
- Refactor token property access to use optional chaining for safer data handling.

try {
const [t, metaData] = await Promise.all([
const [t, pairs, metaData] = await Promise.all([
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Unnecessary Promise.all Destructuring Creates Wasteful API Call

Variable pairs is destructured from Promise.all but never used. The code fetches pairs data via getPairsByTokenUsd(tokenAddress) but doesn't assign it to any state variable, causing the API call to be wasteful. Either remove the pairs variable and the corresponding API call, or assign it to a state variable like the other values (e.g., setPairs(pairs)).

Fix in Cursor Fix in Web

- Add missing import for useTranslation from react-i18next

- Fixes runtime error causing token pages to crash

- Resolves 'useTranslation is not defined' error
- Change condition from truthy check to null check to allow 0 values

- Fixes broken change indicator when percentage is exactly 0

- Now shows neutral styling (white/gray) for zero change instead of hiding
- Make topic lookup case-insensitive

- Add fallback query to fetch token data by symbol when topic doesn't have performance data

- Cache token data for 5 minutes to reduce API calls
Copy link

@cursor cursor bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Topic DTOs Break fromTopics Type Checks

The fromTopics() function still treats topics as string[] with checks like typeof t === 'string', but according to the API changes in this commit, PostDto.topics has been changed from Array<string> to Array<TopicDto> (objects with properties like name, token, etc.). This code will fail to extract token names because it's checking if TopicDto objects are strings. The function should access t.name instead of treating t as a string.

src/features/social/components/TokenCreatedActivityItem.tsx#L31-L38

const fromTopics = () => {
const topics = (item as any)?.topics as string[] | undefined;
if (!Array.isArray(topics)) return null;
const hash = topics.find((t) => typeof t === 'string' && t.startsWith('#'));
if (hash) return hash.replace(/^#/, '');
const tn = topics.find((t) => typeof t === 'string' && t.startsWith('token_name:'));
if (tn) return tn.split(':')[1];
return null;

Fix in Cursor Fix in Web


Bug: Topic mapping breaks with object topics

The code maps topics with .map((t: string) => String(t).toLowerCase()) assuming topics are strings, but PostDto.topics has been changed to Array<TopicDto> in this commit. When t is a TopicDto object, String(t) will produce "[object Object]", not the topic name. This breaks the bio-update detection logic. Should be .map((t: any) => String(t.name || t).toLowerCase()) to handle both old string format and new TopicDto format.

src/views/UserProfile.tsx#L132-L133

for (const p of posts) {
const topics = (Array.isArray((p as any).topics) ? (p as any).topics : []).map((t: string) => String(t).toLowerCase());

Fix in Cursor Fix in Web


- Change condition for fetching token data to ensure it only triggers when normalized is truthy.
- Enhances the fallback mechanism for retrieving token data when performance indicators are missing.
const changePercentFromTopic = topic?.token?.performance?.past_30d?.current_change_percent;

// Fallback: if topic doesn't have token data, try to fetch token by symbol
const shouldFetchToken = !changePercentFromTopic && !!normalized;
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bug: Fetch token only when data missing, not zero.

Incorrect conditional logic for shouldFetchToken: The condition !changePercentFromTopic will be true when changePercentFromTopic is 0, causing an unnecessary token fetch even when the topic already has valid performance data showing 0% change. The condition should be changePercentFromTopic === undefined or changePercentFromTopic == null to only fetch when the data is actually missing, not when it's legitimately zero.

Fix in Cursor Fix in Web

- Add separate query to fetch performance data if token exists but performance is missing

- Fixes issue where hashtags with tokens weren't showing change indicators

- Use TrendminerApi.getTokenPerformance for fallback performance fetch
- Add fallback to check multiple time periods (24h, 7d, 30d) for performance data

- Handle both TopicDto objects and string arrays for backward compatibility

- Fetch performance separately for topic tokens that lack performance data

- Add debug logging for token fetches

- Simplify token fetch condition to always try when no change percent data available
…formance data

- Normalize topic names by removing trailing punctuation when matching

- Fix performance check to verify current_change_percent is not null, not just that period exists

- This fixes #people matching with 'people.' topic and #funding/#trending detecting missing performance data
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants