@liberfi.io/ui-media-track 0.1.267 → 0.1.269
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{api-CApLUcm0.d.mts → api-DhiXNPVw.d.mts} +1 -1
- package/dist/{api-CApLUcm0.d.ts → api-DhiXNPVw.d.ts} +1 -1
- package/dist/client/index.d.mts +1 -1
- package/dist/client/index.d.ts +1 -1
- package/dist/client/index.js.map +1 -1
- package/dist/client/index.mjs.map +1 -1
- package/dist/index.d.mts +21 -2
- package/dist/index.d.ts +21 -2
- package/dist/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +13 -8
|
@@ -143,4 +143,4 @@ interface IMediaTrackClient {
|
|
|
143
143
|
disconnect(): void;
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
export type { GeneratedMemeInfo as G, IMediaTrackClient as I, MediaToken as M,
|
|
146
|
+
export type { GeneratedMemeInfo as G, IMediaTrackClient as I, MediaToken as M, SourceTweet as S, TweetContentMedia as T, TweetUser as a, TweetMedia as b, IMedia as c, SubscribeTweetMediasOptions as d, Tweet as e, TweetContent as f };
|
|
@@ -143,4 +143,4 @@ interface IMediaTrackClient {
|
|
|
143
143
|
disconnect(): void;
|
|
144
144
|
}
|
|
145
145
|
|
|
146
|
-
export type { GeneratedMemeInfo as G, IMediaTrackClient as I, MediaToken as M,
|
|
146
|
+
export type { GeneratedMemeInfo as G, IMediaTrackClient as I, MediaToken as M, SourceTweet as S, TweetContentMedia as T, TweetUser as a, TweetMedia as b, IMedia as c, SubscribeTweetMediasOptions as d, Tweet as e, TweetContent as f };
|
package/dist/client/index.d.mts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { LocaleCode } from '@liberfi.io/i18n';
|
|
2
2
|
import { ISubscription } from '@liberfi.io/types';
|
|
3
|
-
import { I as IMediaTrackClient, c as IMedia,
|
|
3
|
+
import { I as IMediaTrackClient, c as IMedia, d as SubscribeTweetMediasOptions, G as GeneratedMemeInfo, b as TweetMedia, M as MediaToken, e as Tweet, S as SourceTweet, a as TweetUser, f as TweetContent, T as TweetContentMedia } from '../api-DhiXNPVw.mjs';
|
|
4
4
|
|
|
5
5
|
interface MediaTrackClientOptions {
|
|
6
6
|
endpoint: string;
|
package/dist/client/index.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { LocaleCode } from '@liberfi.io/i18n';
|
|
2
2
|
import { ISubscription } from '@liberfi.io/types';
|
|
3
|
-
import { I as IMediaTrackClient, c as IMedia,
|
|
3
|
+
import { I as IMediaTrackClient, c as IMedia, d as SubscribeTweetMediasOptions, G as GeneratedMemeInfo, b as TweetMedia, M as MediaToken, e as Tweet, S as SourceTweet, a as TweetUser, f as TweetContent, T as TweetContentMedia } from '../api-DhiXNPVw.js';
|
|
4
4
|
|
|
5
5
|
interface MediaTrackClientOptions {
|
|
6
6
|
endpoint: string;
|
package/dist/client/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/client/utils.ts","../../src/client/client.ts"],"names":["convertFromSubscribedTweetMedia","from","convertFromSubscribedMediaToken","convertFromSubscribedTweet","convertFromSubscribedSourceTweet","chain","Chain","chainIdBySlug","priceChange","SafeBigNumber","convertFromSubscribedTweetUser","convertFromSubscribedTweetContent","convertFromSubscribedTweetContentMedia","convertFromGenerateMemeResult","toTranslateParamsDTO","media","targetLanguage","options","toTranslateTweetParamsDTO","toGenerateMemeParamsDTO","toGenerateTweetMemeParamsDTO","MediaTrackClient","_MediaTrackClient","endpoint","streamEndpoint","accessToken","token","wsUrl","Centrifuge","err","url","requestOptions","params","httpPost","channel","fn","listeners","ctx","it","Subscription","sub","callback","data","error","res","client"],"mappings":"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","file":"index.js","sourcesContent":["import { LocaleCode } from \"@liberfi.io/i18n\";\nimport { Chain } from \"@liberfi.io/types\";\nimport { chainIdBySlug, SafeBigNumber } from \"@liberfi.io/utils\";\nimport {\n GeneratedMemeInfo,\n IMedia,\n MediaToken,\n SourceTweet,\n Tweet,\n TweetContent,\n TweetContentMedia,\n TweetMedia,\n TweetUser,\n} from \"../types\";\nimport {\n GenerateMemeResult,\n SubscribedMediaToken,\n SubscribedSourceTweet,\n SubscribedTweet,\n SubscribedTweetContent,\n SubscribedTweetContentMedia,\n SubscribedTweetMedia,\n SubscribedTweetUser,\n TranslateTweetRequest,\n} from \"./types\";\n\nexport function convertFromSubscribedTweetMedia(\n from: SubscribedTweetMedia,\n): TweetMedia {\n return {\n id: from.i,\n type: \"tweet\",\n tokenType: from.tt,\n token: from.t ? convertFromSubscribedMediaToken(from.t) : undefined,\n tweet: convertFromSubscribedTweet(from.tw),\n sourceTweet: from.s ? convertFromSubscribedSourceTweet(from.s) : undefined,\n };\n}\n\nexport function convertFromSubscribedMediaToken(\n from: SubscribedMediaToken,\n): MediaToken {\n const chain = from.c === \"sol\" ? Chain.SOLANA : chainIdBySlug(from.c);\n if (!chain) {\n throw new Error(`Unsupported chain: ${from.c}`);\n }\n const priceChange =\n from.p && from.p1 && new SafeBigNumber(from.p1).isPositive()\n ? new SafeBigNumber(from.p)\n .minus(from.p1)\n .div(from.p1)\n .times(100)\n .toString()\n : undefined;\n return {\n chain,\n address: from.a,\n symbol: from.s,\n image: from.i,\n latestPrice: from.p,\n previousPrice: from.p1,\n priceChange,\n };\n}\n\nexport function convertFromSubscribedTweet(from: SubscribedTweet): Tweet {\n return {\n tweetId: from.i,\n type: from.t,\n timestamp: Number(from.ts),\n user: convertFromSubscribedTweetUser(from.u),\n content: convertFromSubscribedTweetContent(from.c),\n };\n}\n\nexport function convertFromSubscribedSourceTweet(\n from: SubscribedSourceTweet,\n): SourceTweet {\n return {\n tweetId: from.i,\n user: convertFromSubscribedTweetUser(from.u),\n content: convertFromSubscribedTweetContent(from.c),\n };\n}\n\nexport function convertFromSubscribedTweetUser(\n from: SubscribedTweetUser,\n): TweetUser {\n return {\n username: from.s,\n screenName: from.n,\n avatar: from.a,\n tags: from.ut,\n };\n}\n\nexport function convertFromSubscribedTweetContent(\n from: SubscribedTweetContent,\n): TweetContent {\n return {\n text: from.t,\n medias: from.m\n ? from.m.map(convertFromSubscribedTweetContentMedia).filter(Boolean)\n : undefined,\n };\n}\n\nexport function convertFromSubscribedTweetContentMedia(\n from: SubscribedTweetContentMedia,\n): TweetContentMedia {\n return {\n type: from.t,\n url: from.u,\n };\n}\n\nexport function convertFromGenerateMemeResult(\n from: GenerateMemeResult,\n): GeneratedMemeInfo {\n return {\n symbol: from.ticker,\n name: from.coin_name,\n image: from.icon_url,\n };\n}\n\nexport function toTranslateParamsDTO(\n media: IMedia,\n targetLanguage: LocaleCode,\n options?: { sourceLanguage?: LocaleCode; sourceTweet?: boolean },\n): TranslateTweetRequest {\n switch (media.type) {\n case \"tweet\":\n return toTranslateTweetParamsDTO(\n media as TweetMedia,\n targetLanguage,\n options,\n );\n default:\n throw new Error(`Unsupported media type: ${media.type}`);\n }\n}\n\nexport function toGenerateMemeParamsDTO(media: IMedia) {\n switch (media.type) {\n case \"tweet\":\n return toGenerateTweetMemeParamsDTO(media as TweetMedia);\n default:\n throw new Error(`Unsupported media type: ${media.type}`);\n }\n}\n\nexport function toGenerateTweetMemeParamsDTO(media: TweetMedia) {\n return {\n tweet_id: media.tweet.tweetId,\n tweet_info: media.tweet.content.text,\n };\n}\n\nexport function toTranslateTweetParamsDTO(\n media: TweetMedia,\n targetLanguage: LocaleCode,\n options?: { sourceLanguage?: LocaleCode; sourceTweet?: boolean },\n): TranslateTweetRequest {\n return {\n res_type: \"tw\",\n res_id: options?.sourceTweet\n ? (media.sourceTweet?.tweetId ?? media.id)\n : media.id,\n source_lang: options?.sourceLanguage,\n target_lang: targetLanguage,\n text:\n (options?.sourceTweet\n ? media.sourceTweet?.content.text\n : media.tweet.content.text) ?? \"\",\n };\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable no-console */\nimport { Centrifuge } from \"@chainstream-io/centrifuge\";\nimport { LocaleCode } from \"@liberfi.io/i18n\";\nimport { ISubscription } from \"@liberfi.io/types\";\nimport { httpPost } from \"@liberfi.io/utils\";\nimport {\n GeneratedMemeInfo,\n IMedia,\n IMediaTrackClient,\n SubscribeTweetMediasOptions,\n} from \"../types\";\nimport {\n GenerateMemeResponse,\n SubscribedTweetMedia,\n TranslateTweetResponse,\n} from \"./types\";\nimport {\n convertFromGenerateMemeResult,\n convertFromSubscribedTweetMedia,\n toGenerateMemeParamsDTO,\n toTranslateParamsDTO,\n} from \"./utils\";\n\nexport interface MediaTrackClientOptions {\n endpoint: string;\n streamEndpoint: string;\n accessToken:\n | string\n | {\n getToken(): Promise<string> | string;\n };\n}\n\nexport class MediaTrackClient implements IMediaTrackClient {\n private client!: Centrifuge;\n private listenersMap: Map<string, Set<(data: any) => void>>;\n private endpoint: string;\n private streamEndpoint: string;\n private accessToken: MediaTrackClientOptions[\"accessToken\"];\n private initPromise: Promise<void> | null = null;\n\n private static get isServer(): boolean {\n return typeof window === \"undefined\";\n }\n\n constructor({\n endpoint,\n streamEndpoint,\n accessToken,\n }: MediaTrackClientOptions) {\n this.endpoint = endpoint;\n this.streamEndpoint = streamEndpoint;\n this.accessToken = accessToken;\n this.listenersMap = new Map();\n\n if (!MediaTrackClient.isServer) {\n this.connect();\n }\n }\n\n private async initClient() {\n if (this.client) {\n return;\n }\n const token = await this.getTokenValue();\n const wsUrl = this.buildWsUrl(this.streamEndpoint, token);\n this.client = new Centrifuge(wsUrl, {\n getToken: async () => {\n return this.getTokenValue();\n },\n });\n\n this.client\n .on(\"connected\", () => {\n console.info(\"[media-track] connected\");\n })\n .on(\"disconnected\", (err) => {\n console.warn(\"[media-track] disconnected\", err);\n })\n .on(\"error\", (err) => {\n console.error(\"[media-track] error: \", err);\n });\n }\n\n private async getTokenValue(): Promise<string> {\n return typeof this.accessToken === \"string\"\n ? this.accessToken\n : await this.accessToken.getToken();\n }\n\n private buildWsUrl(endpoint: string, token: string): string {\n const url = new URL(endpoint);\n url.searchParams.set(\"token\", token);\n return url.toString();\n }\n\n private async ensureInitialized() {\n if (MediaTrackClient.isServer) return;\n if (!this.initPromise) {\n this.connect();\n }\n await this.initPromise;\n }\n\n async translate(\n media: IMedia,\n targetLanguage: LocaleCode,\n options?: { sourceLanguage?: LocaleCode; sourceTweet?: boolean },\n ): Promise<string> {\n const requestOptions = await this._requestOptions();\n const params = toTranslateParamsDTO(media, targetLanguage, options);\n const res = await httpPost<TranslateTweetResponse>(\n `${this.endpoint}/translation`,\n params,\n requestOptions,\n );\n return res.data.target_text;\n }\n\n /**\n * Connect to the media track realtime server.\n * Lazily initializes the Centrifuge client on first call.\n * No-op when called during SSR (Node.js).\n */\n connect() {\n if (MediaTrackClient.isServer) return;\n this.initPromise = this.initClient().then(() => {\n this.client.connect();\n });\n }\n\n /**\n * Disconnect and release the underlying Centrifuge transport.\n */\n disconnect() {\n if (this.client) {\n this.client.disconnect();\n }\n this.initPromise = null;\n }\n\n subscribe<T = any>(channel: string, fn: (data: T) => void): ISubscription {\n let listeners = this.listenersMap.get(channel);\n if (!listeners) {\n listeners = new Set();\n this.listenersMap.set(channel, listeners);\n }\n listeners.add(fn);\n\n this.ensureInitialized().then(() => {\n if (!this.client.getSubscription(channel)) {\n console.info(\"[media-track] create new sub: \", channel);\n\n const sub = this.client.newSubscription(channel, {\n delta: \"fossil\",\n });\n\n sub\n .on(\"subscribed\", () => {\n console.info(\"[media-track] subscribed\", channel);\n })\n .on(\"unsubscribed\", () => {\n console.info(\"[media-track] unsubscribed\", channel);\n })\n .on(\"publication\", (ctx) => {\n const ls = this.listenersMap.get(channel);\n ls?.forEach((it) => it(ctx.data));\n })\n .subscribe();\n }\n });\n\n return new Subscription<T>(this, channel, fn);\n }\n\n unsubscribe<T = any>(channel: string, fn: (data: T) => void) {\n const listeners = this.listenersMap.get(channel);\n if (!listeners) return;\n\n listeners.delete(fn);\n console.info(\n `[media-track] unsubscribe ${channel} listener, remain: ${listeners.size}`,\n );\n\n if (listeners.size === 0) {\n console.info(`[media-track] unsubscribe channel: ${channel}`);\n\n const sub = this.client.getSubscription(channel);\n if (sub) {\n sub.unsubscribe();\n this.client.removeSubscription(sub);\n }\n\n this.listenersMap.delete(channel);\n }\n }\n\n subscribeTweetMedia({\n callback,\n }: SubscribeTweetMediasOptions): ISubscription {\n return this.subscribe(\"x-monitor-basic\", (data: SubscribedTweetMedia) => {\n try {\n callback(convertFromSubscribedTweetMedia(data));\n } catch (error) {\n console.error(\"[media-track] subscribeTweetMedia error: \", error);\n }\n });\n }\n\n subscribeTweetMediaToken({\n callback,\n }: SubscribeTweetMediasOptions): ISubscription {\n return this.subscribe(\"x-monitor-token\", (data: SubscribedTweetMedia) => {\n try {\n callback(convertFromSubscribedTweetMedia(data));\n } catch (error) {\n console.error(\"[media-track] subscribeTweetMediaToken error: \", error);\n }\n });\n }\n\n async generateMeme(media: IMedia): Promise<GeneratedMemeInfo> {\n const requestOptions = await this._requestOptions();\n const params = toGenerateMemeParamsDTO(media);\n const res = await httpPost<GenerateMemeResponse>(\n `${this.endpoint}/meme/generate`,\n params,\n requestOptions,\n );\n return convertFromGenerateMemeResult(res.data);\n }\n\n async _requestOptions(): Promise<Omit<RequestInit, \"method\">> {\n const token = await this.getTokenValue();\n return {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n };\n }\n}\n\nclass Subscription<T> {\n constructor(\n private readonly client: MediaTrackClient,\n private readonly channel: string,\n private readonly fn: (data: T) => void,\n ) {}\n\n unsubscribe() {\n this.client.unsubscribe(this.channel, this.fn);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/client/utils.ts","../../src/client/client.ts"],"names":["convertFromSubscribedTweetMedia","from","convertFromSubscribedMediaToken","convertFromSubscribedTweet","convertFromSubscribedSourceTweet","chain","Chain","chainIdBySlug","priceChange","SafeBigNumber","convertFromSubscribedTweetUser","convertFromSubscribedTweetContent","convertFromSubscribedTweetContentMedia","convertFromGenerateMemeResult","toTranslateParamsDTO","media","targetLanguage","options","toTranslateTweetParamsDTO","toGenerateMemeParamsDTO","toGenerateTweetMemeParamsDTO","MediaTrackClient","_MediaTrackClient","endpoint","streamEndpoint","accessToken","token","wsUrl","Centrifuge","err","url","requestOptions","params","httpPost","channel","fn","listeners","ctx","it","Subscription","sub","callback","data","error","res","client"],"mappings":"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","file":"index.js","sourcesContent":["import { LocaleCode } from \"@liberfi.io/i18n\";\nimport { Chain } from \"@liberfi.io/types\";\nimport { chainIdBySlug, SafeBigNumber } from \"@liberfi.io/utils\";\nimport {\n GeneratedMemeInfo,\n IMedia,\n MediaToken,\n SourceTweet,\n Tweet,\n TweetContent,\n TweetContentMedia,\n TweetMedia,\n TweetUser,\n} from \"../types\";\nimport {\n GenerateMemeResult,\n SubscribedMediaToken,\n SubscribedSourceTweet,\n SubscribedTweet,\n SubscribedTweetContent,\n SubscribedTweetContentMedia,\n SubscribedTweetMedia,\n SubscribedTweetUser,\n TranslateTweetRequest,\n} from \"./types\";\n\nexport function convertFromSubscribedTweetMedia(\n from: SubscribedTweetMedia,\n): TweetMedia {\n return {\n id: from.i,\n type: \"tweet\",\n tokenType: from.tt,\n token: from.t ? convertFromSubscribedMediaToken(from.t) : undefined,\n tweet: convertFromSubscribedTweet(from.tw),\n sourceTweet: from.s ? convertFromSubscribedSourceTweet(from.s) : undefined,\n };\n}\n\nexport function convertFromSubscribedMediaToken(\n from: SubscribedMediaToken,\n): MediaToken {\n const chain = from.c === \"sol\" ? Chain.SOLANA : chainIdBySlug(from.c);\n if (!chain) {\n throw new Error(`Unsupported chain: ${from.c}`);\n }\n const priceChange =\n from.p && from.p1 && new SafeBigNumber(from.p1).isPositive()\n ? new SafeBigNumber(from.p)\n .minus(from.p1)\n .div(from.p1)\n .times(100)\n .toString()\n : undefined;\n return {\n chain,\n address: from.a,\n symbol: from.s,\n image: from.i,\n latestPrice: from.p,\n previousPrice: from.p1,\n priceChange,\n };\n}\n\nexport function convertFromSubscribedTweet(from: SubscribedTweet): Tweet {\n return {\n tweetId: from.i,\n type: from.t,\n timestamp: Number(from.ts),\n user: convertFromSubscribedTweetUser(from.u),\n content: convertFromSubscribedTweetContent(from.c),\n };\n}\n\nexport function convertFromSubscribedSourceTweet(\n from: SubscribedSourceTweet,\n): SourceTweet {\n return {\n tweetId: from.i,\n user: convertFromSubscribedTweetUser(from.u),\n content: convertFromSubscribedTweetContent(from.c),\n };\n}\n\nexport function convertFromSubscribedTweetUser(\n from: SubscribedTweetUser,\n): TweetUser {\n return {\n username: from.s,\n screenName: from.n,\n avatar: from.a,\n tags: from.ut,\n };\n}\n\nexport function convertFromSubscribedTweetContent(\n from: SubscribedTweetContent,\n): TweetContent {\n return {\n text: from.t,\n medias: from.m\n ? from.m.map(convertFromSubscribedTweetContentMedia).filter(Boolean)\n : undefined,\n };\n}\n\nexport function convertFromSubscribedTweetContentMedia(\n from: SubscribedTweetContentMedia,\n): TweetContentMedia {\n return {\n type: from.t,\n url: from.u,\n };\n}\n\nexport function convertFromGenerateMemeResult(\n from: GenerateMemeResult,\n): GeneratedMemeInfo {\n return {\n symbol: from.ticker,\n name: from.coin_name,\n image: from.icon_url,\n };\n}\n\nexport function toTranslateParamsDTO(\n media: IMedia,\n targetLanguage: LocaleCode,\n options?: { sourceLanguage?: LocaleCode; sourceTweet?: boolean },\n): TranslateTweetRequest {\n switch (media.type) {\n case \"tweet\":\n return toTranslateTweetParamsDTO(\n media as TweetMedia,\n targetLanguage,\n options,\n );\n default:\n throw new Error(`Unsupported media type: ${media.type}`);\n }\n}\n\nexport function toGenerateMemeParamsDTO(media: IMedia) {\n switch (media.type) {\n case \"tweet\":\n return toGenerateTweetMemeParamsDTO(media as TweetMedia);\n default:\n throw new Error(`Unsupported media type: ${media.type}`);\n }\n}\n\nexport function toGenerateTweetMemeParamsDTO(media: TweetMedia) {\n return {\n tweet_id: media.tweet.tweetId,\n tweet_info: media.tweet.content.text,\n };\n}\n\nexport function toTranslateTweetParamsDTO(\n media: TweetMedia,\n targetLanguage: LocaleCode,\n options?: { sourceLanguage?: LocaleCode; sourceTweet?: boolean },\n): TranslateTweetRequest {\n return {\n res_type: \"tw\",\n res_id: options?.sourceTweet\n ? (media.sourceTweet?.tweetId ?? media.id)\n : media.id,\n source_lang: options?.sourceLanguage,\n target_lang: targetLanguage,\n text:\n (options?.sourceTweet\n ? media.sourceTweet?.content.text\n : media.tweet.content.text) ?? \"\",\n };\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable no-console */\nimport { Centrifuge } from \"@chainstream-io/centrifuge\";\nimport { LocaleCode } from \"@liberfi.io/i18n\";\nimport { ISubscription } from \"@liberfi.io/types\";\nimport { httpPost } from \"@liberfi.io/utils\";\nimport {\n GeneratedMemeInfo,\n IMedia,\n IMediaTrackClient,\n SubscribeTweetMediasOptions,\n} from \"../types\";\nimport {\n GenerateMemeResponse,\n SubscribedTweetMedia,\n TranslateTweetResponse,\n} from \"./types\";\nimport {\n convertFromGenerateMemeResult,\n convertFromSubscribedTweetMedia,\n toGenerateMemeParamsDTO,\n toTranslateParamsDTO,\n} from \"./utils\";\n\nexport interface MediaTrackClientOptions {\n endpoint: string;\n streamEndpoint: string;\n accessToken:\n | string\n | {\n getToken(): Promise<string> | string;\n };\n}\n\nexport class MediaTrackClient implements IMediaTrackClient {\n private client!: Centrifuge;\n private listenersMap: Map<string, Set<(data: any) => void>>;\n private endpoint: string;\n private streamEndpoint: string;\n private accessToken: MediaTrackClientOptions[\"accessToken\"];\n private initPromise: Promise<void> | null = null;\n\n private static get isServer(): boolean {\n return typeof window === \"undefined\";\n }\n\n constructor({\n endpoint,\n streamEndpoint,\n accessToken,\n }: MediaTrackClientOptions) {\n this.endpoint = endpoint;\n this.streamEndpoint = streamEndpoint;\n this.accessToken = accessToken;\n this.listenersMap = new Map();\n\n if (!MediaTrackClient.isServer) {\n this.connect();\n }\n }\n\n private async initClient() {\n if (this.client) {\n return;\n }\n const token = await this.getTokenValue();\n const wsUrl = this.buildWsUrl(this.streamEndpoint, token);\n this.client = new Centrifuge(wsUrl, {\n getToken: async () => {\n return this.getTokenValue();\n },\n });\n\n this.client\n .on(\"connected\", () => {\n console.info(\"[media-track] connected\");\n })\n .on(\"disconnected\", (err) => {\n console.warn(\"[media-track] disconnected\", err);\n })\n .on(\"error\", (err) => {\n console.error(\"[media-track] error: \", err);\n });\n }\n\n private async getTokenValue(): Promise<string> {\n return typeof this.accessToken === \"string\"\n ? this.accessToken\n : await this.accessToken.getToken();\n }\n\n private buildWsUrl(endpoint: string, token: string): string {\n const url = new URL(endpoint);\n url.searchParams.set(\"token\", token);\n return url.toString();\n }\n\n private async ensureInitialized() {\n if (MediaTrackClient.isServer) return;\n if (!this.initPromise) {\n this.connect();\n }\n await this.initPromise;\n }\n\n async translate(\n media: IMedia,\n targetLanguage: LocaleCode,\n options?: { sourceLanguage?: LocaleCode; sourceTweet?: boolean },\n ): Promise<string> {\n const requestOptions = await this._requestOptions();\n const params = toTranslateParamsDTO(media, targetLanguage, options);\n const res = await httpPost<TranslateTweetResponse>(\n `${this.endpoint}/translation`,\n params,\n requestOptions,\n );\n return res.data.target_text;\n }\n\n /**\n * Connect to the media track realtime server.\n * Lazily initializes the Centrifuge client on first call.\n * No-op when called during SSR (Node.js).\n */\n connect() {\n if (MediaTrackClient.isServer) return;\n this.initPromise = this.initClient().then(() => {\n this.client.connect();\n });\n }\n\n /**\n * Disconnect and release the underlying Centrifuge transport.\n */\n disconnect() {\n if (this.client) {\n this.client.disconnect();\n }\n this.initPromise = null;\n }\n\n subscribe<T = any>(channel: string, fn: (data: T) => void): ISubscription {\n let listeners = this.listenersMap.get(channel);\n if (!listeners) {\n listeners = new Set();\n this.listenersMap.set(channel, listeners);\n }\n listeners.add(fn);\n\n void this.ensureInitialized().then(() => {\n if (!this.client.getSubscription(channel)) {\n console.info(\"[media-track] create new sub: \", channel);\n\n const sub = this.client.newSubscription(channel, {\n delta: \"fossil\",\n });\n\n sub\n .on(\"subscribed\", () => {\n console.info(\"[media-track] subscribed\", channel);\n })\n .on(\"unsubscribed\", () => {\n console.info(\"[media-track] unsubscribed\", channel);\n })\n .on(\"publication\", (ctx) => {\n const ls = this.listenersMap.get(channel);\n ls?.forEach((it) => it(ctx.data));\n })\n .subscribe();\n }\n });\n\n return new Subscription<T>(this, channel, fn);\n }\n\n unsubscribe<T = any>(channel: string, fn: (data: T) => void) {\n const listeners = this.listenersMap.get(channel);\n if (!listeners) return;\n\n listeners.delete(fn);\n console.info(\n `[media-track] unsubscribe ${channel} listener, remain: ${listeners.size}`,\n );\n\n if (listeners.size === 0) {\n console.info(`[media-track] unsubscribe channel: ${channel}`);\n\n const sub = this.client.getSubscription(channel);\n if (sub) {\n sub.unsubscribe();\n this.client.removeSubscription(sub);\n }\n\n this.listenersMap.delete(channel);\n }\n }\n\n subscribeTweetMedia({\n callback,\n }: SubscribeTweetMediasOptions): ISubscription {\n return this.subscribe(\"x-monitor-basic\", (data: SubscribedTweetMedia) => {\n try {\n callback(convertFromSubscribedTweetMedia(data));\n } catch (error) {\n console.error(\"[media-track] subscribeTweetMedia error: \", error);\n }\n });\n }\n\n subscribeTweetMediaToken({\n callback,\n }: SubscribeTweetMediasOptions): ISubscription {\n return this.subscribe(\"x-monitor-token\", (data: SubscribedTweetMedia) => {\n try {\n callback(convertFromSubscribedTweetMedia(data));\n } catch (error) {\n console.error(\"[media-track] subscribeTweetMediaToken error: \", error);\n }\n });\n }\n\n async generateMeme(media: IMedia): Promise<GeneratedMemeInfo> {\n const requestOptions = await this._requestOptions();\n const params = toGenerateMemeParamsDTO(media);\n const res = await httpPost<GenerateMemeResponse>(\n `${this.endpoint}/meme/generate`,\n params,\n requestOptions,\n );\n return convertFromGenerateMemeResult(res.data);\n }\n\n async _requestOptions(): Promise<Omit<RequestInit, \"method\">> {\n const token = await this.getTokenValue();\n return {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n };\n }\n}\n\nclass Subscription<T> {\n constructor(\n private readonly client: MediaTrackClient,\n private readonly channel: string,\n private readonly fn: (data: T) => void,\n ) {}\n\n unsubscribe() {\n this.client.unsubscribe(this.channel, this.fn);\n }\n}\n"]}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/client/utils.ts","../../src/client/client.ts"],"names":["convertFromSubscribedTweetMedia","from","convertFromSubscribedMediaToken","convertFromSubscribedTweet","convertFromSubscribedSourceTweet","chain","Chain","chainIdBySlug","priceChange","SafeBigNumber","convertFromSubscribedTweetUser","convertFromSubscribedTweetContent","convertFromSubscribedTweetContentMedia","convertFromGenerateMemeResult","toTranslateParamsDTO","media","targetLanguage","options","toTranslateTweetParamsDTO","toGenerateMemeParamsDTO","toGenerateTweetMemeParamsDTO","MediaTrackClient","_MediaTrackClient","endpoint","streamEndpoint","accessToken","token","wsUrl","Centrifuge","err","url","requestOptions","params","httpPost","channel","fn","listeners","ctx","it","Subscription","sub","callback","data","error","res","client"],"mappings":"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","file":"index.mjs","sourcesContent":["import { LocaleCode } from \"@liberfi.io/i18n\";\nimport { Chain } from \"@liberfi.io/types\";\nimport { chainIdBySlug, SafeBigNumber } from \"@liberfi.io/utils\";\nimport {\n GeneratedMemeInfo,\n IMedia,\n MediaToken,\n SourceTweet,\n Tweet,\n TweetContent,\n TweetContentMedia,\n TweetMedia,\n TweetUser,\n} from \"../types\";\nimport {\n GenerateMemeResult,\n SubscribedMediaToken,\n SubscribedSourceTweet,\n SubscribedTweet,\n SubscribedTweetContent,\n SubscribedTweetContentMedia,\n SubscribedTweetMedia,\n SubscribedTweetUser,\n TranslateTweetRequest,\n} from \"./types\";\n\nexport function convertFromSubscribedTweetMedia(\n from: SubscribedTweetMedia,\n): TweetMedia {\n return {\n id: from.i,\n type: \"tweet\",\n tokenType: from.tt,\n token: from.t ? convertFromSubscribedMediaToken(from.t) : undefined,\n tweet: convertFromSubscribedTweet(from.tw),\n sourceTweet: from.s ? convertFromSubscribedSourceTweet(from.s) : undefined,\n };\n}\n\nexport function convertFromSubscribedMediaToken(\n from: SubscribedMediaToken,\n): MediaToken {\n const chain = from.c === \"sol\" ? Chain.SOLANA : chainIdBySlug(from.c);\n if (!chain) {\n throw new Error(`Unsupported chain: ${from.c}`);\n }\n const priceChange =\n from.p && from.p1 && new SafeBigNumber(from.p1).isPositive()\n ? new SafeBigNumber(from.p)\n .minus(from.p1)\n .div(from.p1)\n .times(100)\n .toString()\n : undefined;\n return {\n chain,\n address: from.a,\n symbol: from.s,\n image: from.i,\n latestPrice: from.p,\n previousPrice: from.p1,\n priceChange,\n };\n}\n\nexport function convertFromSubscribedTweet(from: SubscribedTweet): Tweet {\n return {\n tweetId: from.i,\n type: from.t,\n timestamp: Number(from.ts),\n user: convertFromSubscribedTweetUser(from.u),\n content: convertFromSubscribedTweetContent(from.c),\n };\n}\n\nexport function convertFromSubscribedSourceTweet(\n from: SubscribedSourceTweet,\n): SourceTweet {\n return {\n tweetId: from.i,\n user: convertFromSubscribedTweetUser(from.u),\n content: convertFromSubscribedTweetContent(from.c),\n };\n}\n\nexport function convertFromSubscribedTweetUser(\n from: SubscribedTweetUser,\n): TweetUser {\n return {\n username: from.s,\n screenName: from.n,\n avatar: from.a,\n tags: from.ut,\n };\n}\n\nexport function convertFromSubscribedTweetContent(\n from: SubscribedTweetContent,\n): TweetContent {\n return {\n text: from.t,\n medias: from.m\n ? from.m.map(convertFromSubscribedTweetContentMedia).filter(Boolean)\n : undefined,\n };\n}\n\nexport function convertFromSubscribedTweetContentMedia(\n from: SubscribedTweetContentMedia,\n): TweetContentMedia {\n return {\n type: from.t,\n url: from.u,\n };\n}\n\nexport function convertFromGenerateMemeResult(\n from: GenerateMemeResult,\n): GeneratedMemeInfo {\n return {\n symbol: from.ticker,\n name: from.coin_name,\n image: from.icon_url,\n };\n}\n\nexport function toTranslateParamsDTO(\n media: IMedia,\n targetLanguage: LocaleCode,\n options?: { sourceLanguage?: LocaleCode; sourceTweet?: boolean },\n): TranslateTweetRequest {\n switch (media.type) {\n case \"tweet\":\n return toTranslateTweetParamsDTO(\n media as TweetMedia,\n targetLanguage,\n options,\n );\n default:\n throw new Error(`Unsupported media type: ${media.type}`);\n }\n}\n\nexport function toGenerateMemeParamsDTO(media: IMedia) {\n switch (media.type) {\n case \"tweet\":\n return toGenerateTweetMemeParamsDTO(media as TweetMedia);\n default:\n throw new Error(`Unsupported media type: ${media.type}`);\n }\n}\n\nexport function toGenerateTweetMemeParamsDTO(media: TweetMedia) {\n return {\n tweet_id: media.tweet.tweetId,\n tweet_info: media.tweet.content.text,\n };\n}\n\nexport function toTranslateTweetParamsDTO(\n media: TweetMedia,\n targetLanguage: LocaleCode,\n options?: { sourceLanguage?: LocaleCode; sourceTweet?: boolean },\n): TranslateTweetRequest {\n return {\n res_type: \"tw\",\n res_id: options?.sourceTweet\n ? (media.sourceTweet?.tweetId ?? media.id)\n : media.id,\n source_lang: options?.sourceLanguage,\n target_lang: targetLanguage,\n text:\n (options?.sourceTweet\n ? media.sourceTweet?.content.text\n : media.tweet.content.text) ?? \"\",\n };\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable no-console */\nimport { Centrifuge } from \"@chainstream-io/centrifuge\";\nimport { LocaleCode } from \"@liberfi.io/i18n\";\nimport { ISubscription } from \"@liberfi.io/types\";\nimport { httpPost } from \"@liberfi.io/utils\";\nimport {\n GeneratedMemeInfo,\n IMedia,\n IMediaTrackClient,\n SubscribeTweetMediasOptions,\n} from \"../types\";\nimport {\n GenerateMemeResponse,\n SubscribedTweetMedia,\n TranslateTweetResponse,\n} from \"./types\";\nimport {\n convertFromGenerateMemeResult,\n convertFromSubscribedTweetMedia,\n toGenerateMemeParamsDTO,\n toTranslateParamsDTO,\n} from \"./utils\";\n\nexport interface MediaTrackClientOptions {\n endpoint: string;\n streamEndpoint: string;\n accessToken:\n | string\n | {\n getToken(): Promise<string> | string;\n };\n}\n\nexport class MediaTrackClient implements IMediaTrackClient {\n private client!: Centrifuge;\n private listenersMap: Map<string, Set<(data: any) => void>>;\n private endpoint: string;\n private streamEndpoint: string;\n private accessToken: MediaTrackClientOptions[\"accessToken\"];\n private initPromise: Promise<void> | null = null;\n\n private static get isServer(): boolean {\n return typeof window === \"undefined\";\n }\n\n constructor({\n endpoint,\n streamEndpoint,\n accessToken,\n }: MediaTrackClientOptions) {\n this.endpoint = endpoint;\n this.streamEndpoint = streamEndpoint;\n this.accessToken = accessToken;\n this.listenersMap = new Map();\n\n if (!MediaTrackClient.isServer) {\n this.connect();\n }\n }\n\n private async initClient() {\n if (this.client) {\n return;\n }\n const token = await this.getTokenValue();\n const wsUrl = this.buildWsUrl(this.streamEndpoint, token);\n this.client = new Centrifuge(wsUrl, {\n getToken: async () => {\n return this.getTokenValue();\n },\n });\n\n this.client\n .on(\"connected\", () => {\n console.info(\"[media-track] connected\");\n })\n .on(\"disconnected\", (err) => {\n console.warn(\"[media-track] disconnected\", err);\n })\n .on(\"error\", (err) => {\n console.error(\"[media-track] error: \", err);\n });\n }\n\n private async getTokenValue(): Promise<string> {\n return typeof this.accessToken === \"string\"\n ? this.accessToken\n : await this.accessToken.getToken();\n }\n\n private buildWsUrl(endpoint: string, token: string): string {\n const url = new URL(endpoint);\n url.searchParams.set(\"token\", token);\n return url.toString();\n }\n\n private async ensureInitialized() {\n if (MediaTrackClient.isServer) return;\n if (!this.initPromise) {\n this.connect();\n }\n await this.initPromise;\n }\n\n async translate(\n media: IMedia,\n targetLanguage: LocaleCode,\n options?: { sourceLanguage?: LocaleCode; sourceTweet?: boolean },\n ): Promise<string> {\n const requestOptions = await this._requestOptions();\n const params = toTranslateParamsDTO(media, targetLanguage, options);\n const res = await httpPost<TranslateTweetResponse>(\n `${this.endpoint}/translation`,\n params,\n requestOptions,\n );\n return res.data.target_text;\n }\n\n /**\n * Connect to the media track realtime server.\n * Lazily initializes the Centrifuge client on first call.\n * No-op when called during SSR (Node.js).\n */\n connect() {\n if (MediaTrackClient.isServer) return;\n this.initPromise = this.initClient().then(() => {\n this.client.connect();\n });\n }\n\n /**\n * Disconnect and release the underlying Centrifuge transport.\n */\n disconnect() {\n if (this.client) {\n this.client.disconnect();\n }\n this.initPromise = null;\n }\n\n subscribe<T = any>(channel: string, fn: (data: T) => void): ISubscription {\n let listeners = this.listenersMap.get(channel);\n if (!listeners) {\n listeners = new Set();\n this.listenersMap.set(channel, listeners);\n }\n listeners.add(fn);\n\n this.ensureInitialized().then(() => {\n if (!this.client.getSubscription(channel)) {\n console.info(\"[media-track] create new sub: \", channel);\n\n const sub = this.client.newSubscription(channel, {\n delta: \"fossil\",\n });\n\n sub\n .on(\"subscribed\", () => {\n console.info(\"[media-track] subscribed\", channel);\n })\n .on(\"unsubscribed\", () => {\n console.info(\"[media-track] unsubscribed\", channel);\n })\n .on(\"publication\", (ctx) => {\n const ls = this.listenersMap.get(channel);\n ls?.forEach((it) => it(ctx.data));\n })\n .subscribe();\n }\n });\n\n return new Subscription<T>(this, channel, fn);\n }\n\n unsubscribe<T = any>(channel: string, fn: (data: T) => void) {\n const listeners = this.listenersMap.get(channel);\n if (!listeners) return;\n\n listeners.delete(fn);\n console.info(\n `[media-track] unsubscribe ${channel} listener, remain: ${listeners.size}`,\n );\n\n if (listeners.size === 0) {\n console.info(`[media-track] unsubscribe channel: ${channel}`);\n\n const sub = this.client.getSubscription(channel);\n if (sub) {\n sub.unsubscribe();\n this.client.removeSubscription(sub);\n }\n\n this.listenersMap.delete(channel);\n }\n }\n\n subscribeTweetMedia({\n callback,\n }: SubscribeTweetMediasOptions): ISubscription {\n return this.subscribe(\"x-monitor-basic\", (data: SubscribedTweetMedia) => {\n try {\n callback(convertFromSubscribedTweetMedia(data));\n } catch (error) {\n console.error(\"[media-track] subscribeTweetMedia error: \", error);\n }\n });\n }\n\n subscribeTweetMediaToken({\n callback,\n }: SubscribeTweetMediasOptions): ISubscription {\n return this.subscribe(\"x-monitor-token\", (data: SubscribedTweetMedia) => {\n try {\n callback(convertFromSubscribedTweetMedia(data));\n } catch (error) {\n console.error(\"[media-track] subscribeTweetMediaToken error: \", error);\n }\n });\n }\n\n async generateMeme(media: IMedia): Promise<GeneratedMemeInfo> {\n const requestOptions = await this._requestOptions();\n const params = toGenerateMemeParamsDTO(media);\n const res = await httpPost<GenerateMemeResponse>(\n `${this.endpoint}/meme/generate`,\n params,\n requestOptions,\n );\n return convertFromGenerateMemeResult(res.data);\n }\n\n async _requestOptions(): Promise<Omit<RequestInit, \"method\">> {\n const token = await this.getTokenValue();\n return {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n };\n }\n}\n\nclass Subscription<T> {\n constructor(\n private readonly client: MediaTrackClient,\n private readonly channel: string,\n private readonly fn: (data: T) => void,\n ) {}\n\n unsubscribe() {\n this.client.unsubscribe(this.channel, this.fn);\n }\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/client/utils.ts","../../src/client/client.ts"],"names":["convertFromSubscribedTweetMedia","from","convertFromSubscribedMediaToken","convertFromSubscribedTweet","convertFromSubscribedSourceTweet","chain","Chain","chainIdBySlug","priceChange","SafeBigNumber","convertFromSubscribedTweetUser","convertFromSubscribedTweetContent","convertFromSubscribedTweetContentMedia","convertFromGenerateMemeResult","toTranslateParamsDTO","media","targetLanguage","options","toTranslateTweetParamsDTO","toGenerateMemeParamsDTO","toGenerateTweetMemeParamsDTO","MediaTrackClient","_MediaTrackClient","endpoint","streamEndpoint","accessToken","token","wsUrl","Centrifuge","err","url","requestOptions","params","httpPost","channel","fn","listeners","ctx","it","Subscription","sub","callback","data","error","res","client"],"mappings":"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","file":"index.mjs","sourcesContent":["import { LocaleCode } from \"@liberfi.io/i18n\";\nimport { Chain } from \"@liberfi.io/types\";\nimport { chainIdBySlug, SafeBigNumber } from \"@liberfi.io/utils\";\nimport {\n GeneratedMemeInfo,\n IMedia,\n MediaToken,\n SourceTweet,\n Tweet,\n TweetContent,\n TweetContentMedia,\n TweetMedia,\n TweetUser,\n} from \"../types\";\nimport {\n GenerateMemeResult,\n SubscribedMediaToken,\n SubscribedSourceTweet,\n SubscribedTweet,\n SubscribedTweetContent,\n SubscribedTweetContentMedia,\n SubscribedTweetMedia,\n SubscribedTweetUser,\n TranslateTweetRequest,\n} from \"./types\";\n\nexport function convertFromSubscribedTweetMedia(\n from: SubscribedTweetMedia,\n): TweetMedia {\n return {\n id: from.i,\n type: \"tweet\",\n tokenType: from.tt,\n token: from.t ? convertFromSubscribedMediaToken(from.t) : undefined,\n tweet: convertFromSubscribedTweet(from.tw),\n sourceTweet: from.s ? convertFromSubscribedSourceTweet(from.s) : undefined,\n };\n}\n\nexport function convertFromSubscribedMediaToken(\n from: SubscribedMediaToken,\n): MediaToken {\n const chain = from.c === \"sol\" ? Chain.SOLANA : chainIdBySlug(from.c);\n if (!chain) {\n throw new Error(`Unsupported chain: ${from.c}`);\n }\n const priceChange =\n from.p && from.p1 && new SafeBigNumber(from.p1).isPositive()\n ? new SafeBigNumber(from.p)\n .minus(from.p1)\n .div(from.p1)\n .times(100)\n .toString()\n : undefined;\n return {\n chain,\n address: from.a,\n symbol: from.s,\n image: from.i,\n latestPrice: from.p,\n previousPrice: from.p1,\n priceChange,\n };\n}\n\nexport function convertFromSubscribedTweet(from: SubscribedTweet): Tweet {\n return {\n tweetId: from.i,\n type: from.t,\n timestamp: Number(from.ts),\n user: convertFromSubscribedTweetUser(from.u),\n content: convertFromSubscribedTweetContent(from.c),\n };\n}\n\nexport function convertFromSubscribedSourceTweet(\n from: SubscribedSourceTweet,\n): SourceTweet {\n return {\n tweetId: from.i,\n user: convertFromSubscribedTweetUser(from.u),\n content: convertFromSubscribedTweetContent(from.c),\n };\n}\n\nexport function convertFromSubscribedTweetUser(\n from: SubscribedTweetUser,\n): TweetUser {\n return {\n username: from.s,\n screenName: from.n,\n avatar: from.a,\n tags: from.ut,\n };\n}\n\nexport function convertFromSubscribedTweetContent(\n from: SubscribedTweetContent,\n): TweetContent {\n return {\n text: from.t,\n medias: from.m\n ? from.m.map(convertFromSubscribedTweetContentMedia).filter(Boolean)\n : undefined,\n };\n}\n\nexport function convertFromSubscribedTweetContentMedia(\n from: SubscribedTweetContentMedia,\n): TweetContentMedia {\n return {\n type: from.t,\n url: from.u,\n };\n}\n\nexport function convertFromGenerateMemeResult(\n from: GenerateMemeResult,\n): GeneratedMemeInfo {\n return {\n symbol: from.ticker,\n name: from.coin_name,\n image: from.icon_url,\n };\n}\n\nexport function toTranslateParamsDTO(\n media: IMedia,\n targetLanguage: LocaleCode,\n options?: { sourceLanguage?: LocaleCode; sourceTweet?: boolean },\n): TranslateTweetRequest {\n switch (media.type) {\n case \"tweet\":\n return toTranslateTweetParamsDTO(\n media as TweetMedia,\n targetLanguage,\n options,\n );\n default:\n throw new Error(`Unsupported media type: ${media.type}`);\n }\n}\n\nexport function toGenerateMemeParamsDTO(media: IMedia) {\n switch (media.type) {\n case \"tweet\":\n return toGenerateTweetMemeParamsDTO(media as TweetMedia);\n default:\n throw new Error(`Unsupported media type: ${media.type}`);\n }\n}\n\nexport function toGenerateTweetMemeParamsDTO(media: TweetMedia) {\n return {\n tweet_id: media.tweet.tweetId,\n tweet_info: media.tweet.content.text,\n };\n}\n\nexport function toTranslateTweetParamsDTO(\n media: TweetMedia,\n targetLanguage: LocaleCode,\n options?: { sourceLanguage?: LocaleCode; sourceTweet?: boolean },\n): TranslateTweetRequest {\n return {\n res_type: \"tw\",\n res_id: options?.sourceTweet\n ? (media.sourceTweet?.tweetId ?? media.id)\n : media.id,\n source_lang: options?.sourceLanguage,\n target_lang: targetLanguage,\n text:\n (options?.sourceTweet\n ? media.sourceTweet?.content.text\n : media.tweet.content.text) ?? \"\",\n };\n}\n","/* eslint-disable @typescript-eslint/no-explicit-any */\n/* eslint-disable no-console */\nimport { Centrifuge } from \"@chainstream-io/centrifuge\";\nimport { LocaleCode } from \"@liberfi.io/i18n\";\nimport { ISubscription } from \"@liberfi.io/types\";\nimport { httpPost } from \"@liberfi.io/utils\";\nimport {\n GeneratedMemeInfo,\n IMedia,\n IMediaTrackClient,\n SubscribeTweetMediasOptions,\n} from \"../types\";\nimport {\n GenerateMemeResponse,\n SubscribedTweetMedia,\n TranslateTweetResponse,\n} from \"./types\";\nimport {\n convertFromGenerateMemeResult,\n convertFromSubscribedTweetMedia,\n toGenerateMemeParamsDTO,\n toTranslateParamsDTO,\n} from \"./utils\";\n\nexport interface MediaTrackClientOptions {\n endpoint: string;\n streamEndpoint: string;\n accessToken:\n | string\n | {\n getToken(): Promise<string> | string;\n };\n}\n\nexport class MediaTrackClient implements IMediaTrackClient {\n private client!: Centrifuge;\n private listenersMap: Map<string, Set<(data: any) => void>>;\n private endpoint: string;\n private streamEndpoint: string;\n private accessToken: MediaTrackClientOptions[\"accessToken\"];\n private initPromise: Promise<void> | null = null;\n\n private static get isServer(): boolean {\n return typeof window === \"undefined\";\n }\n\n constructor({\n endpoint,\n streamEndpoint,\n accessToken,\n }: MediaTrackClientOptions) {\n this.endpoint = endpoint;\n this.streamEndpoint = streamEndpoint;\n this.accessToken = accessToken;\n this.listenersMap = new Map();\n\n if (!MediaTrackClient.isServer) {\n this.connect();\n }\n }\n\n private async initClient() {\n if (this.client) {\n return;\n }\n const token = await this.getTokenValue();\n const wsUrl = this.buildWsUrl(this.streamEndpoint, token);\n this.client = new Centrifuge(wsUrl, {\n getToken: async () => {\n return this.getTokenValue();\n },\n });\n\n this.client\n .on(\"connected\", () => {\n console.info(\"[media-track] connected\");\n })\n .on(\"disconnected\", (err) => {\n console.warn(\"[media-track] disconnected\", err);\n })\n .on(\"error\", (err) => {\n console.error(\"[media-track] error: \", err);\n });\n }\n\n private async getTokenValue(): Promise<string> {\n return typeof this.accessToken === \"string\"\n ? this.accessToken\n : await this.accessToken.getToken();\n }\n\n private buildWsUrl(endpoint: string, token: string): string {\n const url = new URL(endpoint);\n url.searchParams.set(\"token\", token);\n return url.toString();\n }\n\n private async ensureInitialized() {\n if (MediaTrackClient.isServer) return;\n if (!this.initPromise) {\n this.connect();\n }\n await this.initPromise;\n }\n\n async translate(\n media: IMedia,\n targetLanguage: LocaleCode,\n options?: { sourceLanguage?: LocaleCode; sourceTweet?: boolean },\n ): Promise<string> {\n const requestOptions = await this._requestOptions();\n const params = toTranslateParamsDTO(media, targetLanguage, options);\n const res = await httpPost<TranslateTweetResponse>(\n `${this.endpoint}/translation`,\n params,\n requestOptions,\n );\n return res.data.target_text;\n }\n\n /**\n * Connect to the media track realtime server.\n * Lazily initializes the Centrifuge client on first call.\n * No-op when called during SSR (Node.js).\n */\n connect() {\n if (MediaTrackClient.isServer) return;\n this.initPromise = this.initClient().then(() => {\n this.client.connect();\n });\n }\n\n /**\n * Disconnect and release the underlying Centrifuge transport.\n */\n disconnect() {\n if (this.client) {\n this.client.disconnect();\n }\n this.initPromise = null;\n }\n\n subscribe<T = any>(channel: string, fn: (data: T) => void): ISubscription {\n let listeners = this.listenersMap.get(channel);\n if (!listeners) {\n listeners = new Set();\n this.listenersMap.set(channel, listeners);\n }\n listeners.add(fn);\n\n void this.ensureInitialized().then(() => {\n if (!this.client.getSubscription(channel)) {\n console.info(\"[media-track] create new sub: \", channel);\n\n const sub = this.client.newSubscription(channel, {\n delta: \"fossil\",\n });\n\n sub\n .on(\"subscribed\", () => {\n console.info(\"[media-track] subscribed\", channel);\n })\n .on(\"unsubscribed\", () => {\n console.info(\"[media-track] unsubscribed\", channel);\n })\n .on(\"publication\", (ctx) => {\n const ls = this.listenersMap.get(channel);\n ls?.forEach((it) => it(ctx.data));\n })\n .subscribe();\n }\n });\n\n return new Subscription<T>(this, channel, fn);\n }\n\n unsubscribe<T = any>(channel: string, fn: (data: T) => void) {\n const listeners = this.listenersMap.get(channel);\n if (!listeners) return;\n\n listeners.delete(fn);\n console.info(\n `[media-track] unsubscribe ${channel} listener, remain: ${listeners.size}`,\n );\n\n if (listeners.size === 0) {\n console.info(`[media-track] unsubscribe channel: ${channel}`);\n\n const sub = this.client.getSubscription(channel);\n if (sub) {\n sub.unsubscribe();\n this.client.removeSubscription(sub);\n }\n\n this.listenersMap.delete(channel);\n }\n }\n\n subscribeTweetMedia({\n callback,\n }: SubscribeTweetMediasOptions): ISubscription {\n return this.subscribe(\"x-monitor-basic\", (data: SubscribedTweetMedia) => {\n try {\n callback(convertFromSubscribedTweetMedia(data));\n } catch (error) {\n console.error(\"[media-track] subscribeTweetMedia error: \", error);\n }\n });\n }\n\n subscribeTweetMediaToken({\n callback,\n }: SubscribeTweetMediasOptions): ISubscription {\n return this.subscribe(\"x-monitor-token\", (data: SubscribedTweetMedia) => {\n try {\n callback(convertFromSubscribedTweetMedia(data));\n } catch (error) {\n console.error(\"[media-track] subscribeTweetMediaToken error: \", error);\n }\n });\n }\n\n async generateMeme(media: IMedia): Promise<GeneratedMemeInfo> {\n const requestOptions = await this._requestOptions();\n const params = toGenerateMemeParamsDTO(media);\n const res = await httpPost<GenerateMemeResponse>(\n `${this.endpoint}/meme/generate`,\n params,\n requestOptions,\n );\n return convertFromGenerateMemeResult(res.data);\n }\n\n async _requestOptions(): Promise<Omit<RequestInit, \"method\">> {\n const token = await this.getTokenValue();\n return {\n headers: {\n Authorization: `Bearer ${token}`,\n },\n };\n }\n}\n\nclass Subscription<T> {\n constructor(\n private readonly client: MediaTrackClient,\n private readonly channel: string,\n private readonly fn: (data: T) => void,\n ) {}\n\n unsubscribe() {\n this.client.unsubscribe(this.channel, this.fn);\n }\n}\n"]}
|
package/dist/index.d.mts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { T as TweetContentMedia, a as TweetUser, b as TweetMedia, I as IMediaTrackClient, G as GeneratedMemeInfo } from './api-
|
|
2
|
+
import { T as TweetContentMedia, a as TweetUser, b as TweetMedia, I as IMediaTrackClient, G as GeneratedMemeInfo } from './api-DhiXNPVw.mjs';
|
|
3
|
+
export { c as IMedia, M as MediaToken, S as SourceTweet, d as SubscribeTweetMediasOptions, e as Tweet, f as TweetContent } from './api-DhiXNPVw.mjs';
|
|
3
4
|
import * as React$1 from 'react';
|
|
4
5
|
import React__default, { PropsWithChildren } from 'react';
|
|
5
6
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
@@ -132,10 +133,28 @@ interface MediaTrackContextValue {
|
|
|
132
133
|
}
|
|
133
134
|
declare const MediaTrackContext: React$1.Context<MediaTrackContextValue>;
|
|
134
135
|
|
|
136
|
+
type MediaTrackUnsubscribe = () => void;
|
|
137
|
+
interface MediaTrackSubscription {
|
|
138
|
+
unsubscribe: MediaTrackUnsubscribe;
|
|
139
|
+
}
|
|
140
|
+
interface MediaTrackRuntime<T = unknown> {
|
|
141
|
+
readonly generation: number;
|
|
142
|
+
connect(): void;
|
|
143
|
+
disconnect(): void;
|
|
144
|
+
setLocaleTransform(transform: ((payload: T) => T) | null): void;
|
|
145
|
+
subscribe(channel: string, listener: (payload: T) => void): MediaTrackSubscription;
|
|
146
|
+
publish(channel: string, payload: T): void;
|
|
147
|
+
}
|
|
148
|
+
declare function createMediaTrackRuntime<T = unknown>(): MediaTrackRuntime<T>;
|
|
149
|
+
|
|
150
|
+
declare const MediaTrackRuntimeContext: React$1.Context<MediaTrackRuntime<TweetMedia> | null>;
|
|
151
|
+
|
|
135
152
|
declare function useGenerateTweetMediaMemeMutation(options?: Omit<UseMutationOptions<GeneratedMemeInfo, Error, TweetMedia, string[]>, "mutationFn">): _tanstack_react_query.UseMutationResult<GeneratedMemeInfo, Error, TweetMedia, string[]>;
|
|
136
153
|
|
|
137
154
|
declare function useMediaTrackClient(): IMediaTrackClient;
|
|
138
155
|
|
|
156
|
+
declare function useMediaTrackRuntime(): MediaTrackRuntime<TweetMedia>;
|
|
157
|
+
|
|
139
158
|
declare function useMediaTrackContext(): MediaTrackContextValue;
|
|
140
159
|
|
|
141
160
|
interface UseTranslateTweetMediaParams {
|
|
@@ -154,4 +173,4 @@ type MediaTrackProviderProps = PropsWithChildren<{
|
|
|
154
173
|
}>;
|
|
155
174
|
declare function MediaTrackProvider({ client, children, }: MediaTrackProviderProps): react_jsx_runtime.JSX.Element;
|
|
156
175
|
|
|
157
|
-
export { MediaImage, MediaTrackContext, type MediaTrackContextValue, MediaTrackProvider, type MediaTrackProviderProps, MediaVideo, Medias, TextExpand, Translate, TweetItem, TweetOriginal, TweetQuote, TweetReply, TweetRetweet, TweetSkeleton, TweetSkeletonList, TweetSource, Tweets, TweetsWidget, type TweetsWidgetProps, type UseTranslateTweetMediaParams, UserAvatar, UserInfo, translateTweetMedia, useGenerateTweetMediaMemeMutation, useMediaTrackClient, useMediaTrackContext, useTranslateTweetMediaMutation, useTweets };
|
|
176
|
+
export { GeneratedMemeInfo, IMediaTrackClient, MediaImage, MediaTrackContext, type MediaTrackContextValue, MediaTrackProvider, type MediaTrackProviderProps, type MediaTrackRuntime, MediaTrackRuntimeContext, MediaVideo, Medias, TextExpand, Translate, TweetContentMedia, TweetItem, TweetMedia, TweetOriginal, TweetQuote, TweetReply, TweetRetweet, TweetSkeleton, TweetSkeletonList, TweetSource, TweetUser, Tweets, TweetsWidget, type TweetsWidgetProps, type UseTranslateTweetMediaParams, UserAvatar, UserInfo, createMediaTrackRuntime, translateTweetMedia, useGenerateTweetMediaMemeMutation, useMediaTrackClient, useMediaTrackContext, useMediaTrackRuntime, useTranslateTweetMediaMutation, useTweets };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
-
import { T as TweetContentMedia, a as TweetUser, b as TweetMedia, I as IMediaTrackClient, G as GeneratedMemeInfo } from './api-
|
|
2
|
+
import { T as TweetContentMedia, a as TweetUser, b as TweetMedia, I as IMediaTrackClient, G as GeneratedMemeInfo } from './api-DhiXNPVw.js';
|
|
3
|
+
export { c as IMedia, M as MediaToken, S as SourceTweet, d as SubscribeTweetMediasOptions, e as Tweet, f as TweetContent } from './api-DhiXNPVw.js';
|
|
3
4
|
import * as React$1 from 'react';
|
|
4
5
|
import React__default, { PropsWithChildren } from 'react';
|
|
5
6
|
import * as _tanstack_react_query from '@tanstack/react-query';
|
|
@@ -132,10 +133,28 @@ interface MediaTrackContextValue {
|
|
|
132
133
|
}
|
|
133
134
|
declare const MediaTrackContext: React$1.Context<MediaTrackContextValue>;
|
|
134
135
|
|
|
136
|
+
type MediaTrackUnsubscribe = () => void;
|
|
137
|
+
interface MediaTrackSubscription {
|
|
138
|
+
unsubscribe: MediaTrackUnsubscribe;
|
|
139
|
+
}
|
|
140
|
+
interface MediaTrackRuntime<T = unknown> {
|
|
141
|
+
readonly generation: number;
|
|
142
|
+
connect(): void;
|
|
143
|
+
disconnect(): void;
|
|
144
|
+
setLocaleTransform(transform: ((payload: T) => T) | null): void;
|
|
145
|
+
subscribe(channel: string, listener: (payload: T) => void): MediaTrackSubscription;
|
|
146
|
+
publish(channel: string, payload: T): void;
|
|
147
|
+
}
|
|
148
|
+
declare function createMediaTrackRuntime<T = unknown>(): MediaTrackRuntime<T>;
|
|
149
|
+
|
|
150
|
+
declare const MediaTrackRuntimeContext: React$1.Context<MediaTrackRuntime<TweetMedia> | null>;
|
|
151
|
+
|
|
135
152
|
declare function useGenerateTweetMediaMemeMutation(options?: Omit<UseMutationOptions<GeneratedMemeInfo, Error, TweetMedia, string[]>, "mutationFn">): _tanstack_react_query.UseMutationResult<GeneratedMemeInfo, Error, TweetMedia, string[]>;
|
|
136
153
|
|
|
137
154
|
declare function useMediaTrackClient(): IMediaTrackClient;
|
|
138
155
|
|
|
156
|
+
declare function useMediaTrackRuntime(): MediaTrackRuntime<TweetMedia>;
|
|
157
|
+
|
|
139
158
|
declare function useMediaTrackContext(): MediaTrackContextValue;
|
|
140
159
|
|
|
141
160
|
interface UseTranslateTweetMediaParams {
|
|
@@ -154,4 +173,4 @@ type MediaTrackProviderProps = PropsWithChildren<{
|
|
|
154
173
|
}>;
|
|
155
174
|
declare function MediaTrackProvider({ client, children, }: MediaTrackProviderProps): react_jsx_runtime.JSX.Element;
|
|
156
175
|
|
|
157
|
-
export { MediaImage, MediaTrackContext, type MediaTrackContextValue, MediaTrackProvider, type MediaTrackProviderProps, MediaVideo, Medias, TextExpand, Translate, TweetItem, TweetOriginal, TweetQuote, TweetReply, TweetRetweet, TweetSkeleton, TweetSkeletonList, TweetSource, Tweets, TweetsWidget, type TweetsWidgetProps, type UseTranslateTweetMediaParams, UserAvatar, UserInfo, translateTweetMedia, useGenerateTweetMediaMemeMutation, useMediaTrackClient, useMediaTrackContext, useTranslateTweetMediaMutation, useTweets };
|
|
176
|
+
export { GeneratedMemeInfo, IMediaTrackClient, MediaImage, MediaTrackContext, type MediaTrackContextValue, MediaTrackProvider, type MediaTrackProviderProps, type MediaTrackRuntime, MediaTrackRuntimeContext, MediaVideo, Medias, TextExpand, Translate, TweetContentMedia, TweetItem, TweetMedia, TweetOriginal, TweetQuote, TweetReply, TweetRetweet, TweetSkeleton, TweetSkeletonList, TweetSource, TweetUser, Tweets, TweetsWidget, type TweetsWidgetProps, type UseTranslateTweetMediaParams, UserAvatar, UserInfo, createMediaTrackRuntime, translateTweetMedia, useGenerateTweetMediaMemeMutation, useMediaTrackClient, useMediaTrackContext, useMediaTrackRuntime, useTranslateTweetMediaMutation, useTweets };
|
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
'use strict';var hooks=require('@liberfi.io/hooks'),ui=require('@liberfi.io/ui'),jsxRuntime=require('react/jsx-runtime'),utils=require('@liberfi.io/utils'),react=require('react'),i18n=require('@liberfi.io/i18n'),reactQuery=require('@tanstack/react-query');function F({src:e}){let[t,{setTrue:r}]=hooks.useBoolean(false);return e?jsxRuntime.jsx(ui.Skeleton,{isLoaded:t,className:"w-full h-auto",children:jsxRuntime.jsx("img",{src:e,className:"w-full h-full object-cover aspect-video",onLoad:()=>{r();}})}):null}function V({src:e}){return e?jsxRuntime.jsx("div",{className:"w-full h-full overflow-hidden rounded-md mt-2",children:jsxRuntime.jsx("iframe",{className:"w-full h-full aspect-video",src:e,allowFullScreen:true})}):null}function W({medias:e,tweetHref:t}){let r=e.filter(s=>s.type==="image"),a=e.filter(s=>s.type==="video"),n=()=>a.length?jsxRuntime.jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:a.map(s=>jsxRuntime.jsx(V,{src:s.url},s.url))}):null,i=()=>r.length?jsxRuntime.jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:r.map(s=>jsxRuntime.jsx(ui.Link,{href:t,target:"_blank",children:jsxRuntime.jsx(F,{src:s.url})},s.url))}):null;return jsxRuntime.jsxs("div",{className:"flex flex-col gap-2",children:[n(),i()]})}function D({url:e,name:t="",size:r=36}){let a=react.useMemo(()=>t?t.slice(0,2):"N/A",[t]);return jsxRuntime.jsx(ui.Skeleton,{className:"flex rounded-full flex-shrink-0",style:{width:r,height:r},isLoaded:!!e,children:jsxRuntime.jsx(ui.Avatar,{size:"md",color:"primary",radius:"full",showFallback:true,name:a,src:e,style:{width:r,height:r}})})}function $({user:e,renderTimestamp:t,renderActions:r}){return jsxRuntime.jsxs("div",{className:"flex items-center justify-between gap-1",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-1",children:[jsxRuntime.jsx(D,{url:e.avatar,name:e.username}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxRuntime.jsxs("div",{className:"flex flex-row items-baseline gap-1",children:[jsxRuntime.jsx("span",{className:"text-foreground font-semibold truncate leading-none",children:e.username}),t]}),jsxRuntime.jsxs(ui.Link,{target:"_blank",underline:"hover",className:"text-default-500 text-sm leading-none",href:utils.twitterUserUrl(e.screenName??e.username),children:["@",e.screenName??e.username]})]})]}),r]})}var b=react.createContext({});function Q(){let e=react.useContext(b);if(!e)throw new Error("useMediaTrackContext must be used within a MediaTrackProvider");return e}function h(){let{client:e}=Q();return e}function ro(e={}){let t=h();return reactQuery.useMutation({mutationFn:async r=>t.generateMeme(r),...e})}async function Ce(e,{media:t,targetLanguage:r,options:a}){return await e.translate(t,r,a)}function Z(e={}){let t=h();return reactQuery.useMutation({mutationFn:async r=>Ce(t,r),...e})}function y(e){let t=/(https?:\/\/[^\s]+|www\.[^\s]+)/gi,r=/#[\w]+/g,a=/\$[A-Za-z][A-Za-z0-9_]*/g,n=[],i;for(;(i=t.exec(e))!==null;)n.push({index:i.index,length:i[0].length,text:i[0],type:"url"});for(;(i=r.exec(e))!==null;){let o=i.index;n.some(d=>o>=d.index&&o<d.index+d.length)||n.push({index:o,length:i[0].length,text:i[0],type:"hashtag"});}for(;(i=a.exec(e))!==null;){let o=i.index;n.some(d=>o>=d.index&&o<d.index+d.length)||n.push({index:o,length:i[0].length,text:i[0],type:"symbol"});}n.sort((o,p)=>o.index-p.index);let s=[],m=0,l=0;return n.forEach(o=>{if(o.index>m&&s.push(e.slice(m,o.index)),o.type==="url"){let p=o.text.startsWith("http")?o.text:`https://${o.text}`;s.push(jsxRuntime.jsx("a",{href:p,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:d=>d.stopPropagation(),children:o.text},l++));}else if(o.type==="hashtag"){let d=`https://x.com/hashtag/${o.text.slice(1)}`;s.push(jsxRuntime.jsx("a",{href:d,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:x=>x.stopPropagation(),children:o.text},l++));}else o.type==="symbol"&&s.push(jsxRuntime.jsx("span",{className:"text-primary",children:o.text},l++));m=o.index+o.length;}),m<e.length&&s.push(e.slice(m)),s.length>0?s:[e]}function q({data:e,embed:t,renderActions:r}){let[a,{toggle:n}]=hooks.useBoolean(false),{t:i,i18n:s}=i18n.useTranslation(),{mutateAsync:m,isPending:l}=Z(),[o,p]=react.useState(null),d=react.useCallback(async x=>{if(x.stopPropagation(),n(),!o){let A=await m({media:e,targetLanguage:s.language,options:{sourceTweet:t}}),ue=y(A);p(ue);}},[n,m,e,s.language,o]);return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-1 text-xs",children:[jsxRuntime.jsxs("div",{onClick:d,className:"flex items-center gap-0.5 cursor-pointer text-primary hover:text-foreground",children:[jsxRuntime.jsx(ui.TranslateIcon,{width:"14",height:"14"}),i(a?"mediaTrack.tweets.translate.hide":"mediaTrack.tweets.translate.show")]}),r]}),jsxRuntime.jsx("div",{className:ui.cn(!a&&"hidden"),onClick:x=>{x.stopPropagation();},children:a&&jsxRuntime.jsxs("div",{className:"bg-content2 rounded-md p-2 text-default-900 text-sm leading-5",children:[o,l&&jsxRuntime.jsx(ui.Skeleton,{className:"w-full h-4 rounded-md"})]})})]})}function K({isExpanded:e,onToggleExpand:t}){let{t:r}=i18n.useTranslation(),a=()=>e?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(ui.ChevronUpIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",r("mediaTrack.tweets.collapse")]}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(ui.ChevronDownIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",r("mediaTrack.tweets.expand")]});return e===void 0?null:jsxRuntime.jsxs("div",{className:"flex items-center gap-1",children:[jsxRuntime.jsx("div",{className:"w-px h-2.5 bg-line-300"}),jsxRuntime.jsx("button",{onClick:n=>{n.stopPropagation(),t?.(!e);},className:"flex items-center text-default-500 hover:text-foreground text-xs",children:a()})]})}function X({content:e,isExpanded:t=false,onLoad:r}){let a=react.useRef(null),n=react.useMemo(()=>y(e),[e]);return react.useEffect(()=>{let i=a.current;!r||!i||i.scrollHeight>i.clientHeight&&r?.();},[t]),jsxRuntime.jsx("div",{ref:a,className:["text-default-900 text-sm leading-5",t?"":"line-clamp-3"].join(" "),onClick:i=>{i.stopPropagation();},children:n})}function u({data:e,headerActions:t,footerActions:r,embed:a=false,indicator:n,children:i}){let[s,m]=react.useState(void 0),l=react.useMemo(()=>a?"bg-default-50 rounded-lg p-3 w-full mx-auto":"bg-default-100 hover:bg-default-200 rounded-lg p-3 w-full mx-auto",[a]),o=react.useMemo(()=>a?e.sourceTweet:e.tweet,[e,a]),p=hooks.useTickAge(o.timestamp);return jsxRuntime.jsxs("div",{className:ui.cn("flex flex-col gap-1.5 cursor-pointer",l),onClick:()=>{window.open(utils.twitterTweetUrl(o.tweetId),"_blank");},children:[jsxRuntime.jsx($,{user:o.user,renderTimestamp:a?void 0:jsxRuntime.jsx("div",{className:"text-xs text-primary",children:utils.formatAge(p)}),renderActions:t}),n,o.content.text&&jsxRuntime.jsx(X,{content:o.content.text,isExpanded:s,onLoad:()=>m(false)}),o.content.text&&jsxRuntime.jsx(q,{data:e,embed:a,text:o.content.text,renderActions:jsxRuntime.jsx(K,{isExpanded:s,onToggleExpand:m})}),jsxRuntime.jsx("div",{className:ui.cn((!o.content.medias||o.content.medias.length===0)&&"hidden"),children:o.content.medias&&o.content.medias.length>0&&jsxRuntime.jsx(W,{medias:o.content.medias,tweetHref:utils.twitterTweetUrl(o.tweetId)})}),i,r]})}function te({data:e,headerActions:t,footerActions:r}){return jsxRuntime.jsx(u,{data:e,headerActions:t,footerActions:r})}function re({data:e,headerActions:t,footerActions:r}){let n=!!e.sourceTweet;return jsxRuntime.jsx(u,{data:e,headerActions:t,footerActions:r,children:n?jsxRuntime.jsx(u,{data:e,embed:true}):null})}function ne({data:e,headerActions:t,footerActions:r}){let a=e.sourceTweet,n=!!a,i=react.useMemo(()=>jsxRuntime.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[jsxRuntime.jsx("span",{children:"Replying to"}),n&&jsxRuntime.jsxs(ui.Link,{className:"text-sm",underline:"hover",target:"_blank",href:utils.twitterUserUrl(a.user.screenName??a.user.username),children:["@",a.user.screenName??a.user.username]})]}),[n,a]);return jsxRuntime.jsx(u,{data:e,indicator:i,headerActions:t,footerActions:r,children:n?jsxRuntime.jsx(u,{data:e,embed:true}):null})}function ie({data:e,headerActions:t,footerActions:r}){let a=e.sourceTweet,n=!!a,i=react.useMemo(()=>jsxRuntime.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[jsxRuntime.jsx("span",{children:"Retweeted by"}),n&&jsxRuntime.jsxs(ui.Link,{className:"text-sm",underline:"hover",target:"_blank",href:utils.twitterUserUrl(a.user.screenName??a.user.username),children:["@",a.user.screenName??a.user.username]})]}),[n,a]);return jsxRuntime.jsx(u,{data:e,indicator:i,headerActions:t,footerActions:r,children:n?jsxRuntime.jsx(u,{data:e,embed:true}):null})}function le({data:e,headerActions:t,footerActions:r,embed:a=false,children:n,loading:i=false}){if(i||!e)return jsxRuntime.jsx(tt,{embed:a});let s=e.tweet.type;return jsxRuntime.jsx("div",{className:"w-full",children:(()=>{let l={data:e,headerActions:t,footerActions:r,embed:a,children:n};switch(s){case "reply":return jsxRuntime.jsx(ne,{...l});case "retweet":return jsxRuntime.jsx(ie,{...l});case "quote":return jsxRuntime.jsx(re,{...l});default:return jsxRuntime.jsx(te,{...l})}})()})}function tt({embed:e=false}){return jsxRuntime.jsxs("div",{className:["flex flex-col gap-2",e?"bg-default-50 rounded-lg p-3 w-full mx-auto":"bg-default-100 rounded-lg p-3 w-full mx-auto"].join(" "),children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-3",children:[jsxRuntime.jsx(ui.Skeleton,{className:"w-10 h-10 rounded-full"}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-1 flex-1",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-24"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-3 w-16"})]}),jsxRuntime.jsx(ui.Skeleton,{className:"h-3 w-12"})]}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-2",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-full"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-3/4"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-1/2"})]}),jsxRuntime.jsx(ui.Skeleton,{className:"h-48 w-full rounded-lg"}),jsxRuntime.jsxs("div",{className:"flex justify-between items-center pt-2",children:[jsxRuntime.jsxs("div",{className:"flex gap-4",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-16"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-16"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-16"})]}),jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-20"})]})]})}function ce({token:e}){let t=new utils.SafeBigNumber(e.priceChange??"0").isPositive()?"primary":"danger";return jsxRuntime.jsxs(ui.Button,{color:t,variant:"flat",size:"sm",radius:"full",startContent:jsxRuntime.jsx(ct,{token:e}),children:[jsxRuntime.jsx("span",{children:e.symbol}),jsxRuntime.jsx("span",{children:e.priceChange?utils.formatPercent(Number(e.priceChange)/100):"--"})]})}function ct({token:e}){let t=react.useMemo(()=>jsxRuntime.jsx(ui.Image,{className:"w-full h-full",src:e.image,alt:e.chain}),[e.chain]);return jsxRuntime.jsx(ui.Badge,{className:"w-2.5 h-2.5 p-0 border",size:"sm",content:t,shape:"circle",placement:"bottom-right",children:jsxRuntime.jsx(ui.Avatar,{className:"w-5 h-5",radius:"full",src:e.image})})}function de({data:e,loading:t,setIsPaused:r,customHeaderActions:a,customFooterActions:n}){let i=react.useCallback(s=>jsxRuntime.jsxs("div",{className:"flex gap-2.5 justify-between",children:[s.token&&jsxRuntime.jsx(ce,{token:s.token}),n?.(s)]}),[n]);return jsxRuntime.jsx("div",{className:"flex flex-col gap-2.5",onMouseEnter:()=>r(true),onMouseLeave:()=>r(false),children:e.map(s=>jsxRuntime.jsx(le,{data:s,headerActions:a?.(s),footerActions:i(s),loading:t},s.id))})}function ft(){return jsxRuntime.jsxs("div",{className:"flex flex-col gap-2 bg-default-100 rounded-lg p-3 w-full mx-auto",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-3",children:[jsxRuntime.jsx(ui.Skeleton,{className:"w-10 h-10 rounded-full"}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-1 flex-1",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-40 rounded-md"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-3 w-32 rounded-md"})]})]}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-2",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-full rounded-md"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-3/4 rounded-md"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-1/2 rounded-md"})]}),jsxRuntime.jsx(ui.Skeleton,{className:"h-48 w-full rounded-lg"})]})}function me({count:e=3}){return jsxRuntime.jsx("div",{className:"flex flex-col gap-2",children:Array.from({length:e}).map((t,r)=>jsxRuntime.jsx(ft,{},r))})}var pe=()=>{let[e,t]=react.useState([]),[r,a]=react.useState(true),[n,i]=react.useState(false),s=h(),m=react.useCallback(l=>{t(o=>{let p=o.findIndex(x=>x.id===l.id),d;if(p>=0)d=o.map((x,A)=>A===p?l:x);else {if(n)return o;d=[l,...o];}return d.slice(0,30)}),a(false);},[n]);return react.useEffect(()=>{let l=s.subscribeTweetMedia({callback:m}),o=s.subscribeTweetMediaToken({callback:m});return ()=>{l.unsubscribe(),o.unsubscribe();}},[s,m]),{medias:e,loading:r,isPaused:n,setIsPaused:i}};function oa({onPauseChange:e,customHeaderActions:t,customFooterActions:r}){let{medias:a,loading:n,isPaused:i,setIsPaused:s}=pe();return react.useEffect(()=>{e?.(i);},[i,e]),n?jsxRuntime.jsx(me,{count:3}):jsxRuntime.jsx(de,{data:a,loading:n,setIsPaused:s,customHeaderActions:t,customFooterActions:r})}function ua({client:e,children:t}){return jsxRuntime.jsx(b.Provider,{value:{client:e},children:t})}
|
|
2
|
-
exports.MediaImage=
|
|
1
|
+
'use strict';var hooks=require('@liberfi.io/hooks'),ui=require('@liberfi.io/ui'),jsxRuntime=require('react/jsx-runtime'),utils=require('@liberfi.io/utils'),react=require('react'),i18n=require('@liberfi.io/i18n'),reactQuery=require('@tanstack/react-query');function S({src:e}){let[t,{setTrue:r}]=hooks.useBoolean(false);return e?jsxRuntime.jsx(ui.Skeleton,{isLoaded:t,className:"w-full h-auto",children:jsxRuntime.jsx("img",{src:e,className:"w-full h-full object-cover aspect-video",onLoad:()=>{r();}})}):null}function E({src:e}){return e?jsxRuntime.jsx("div",{className:"w-full h-full overflow-hidden rounded-md mt-2",children:jsxRuntime.jsx("iframe",{className:"w-full h-full aspect-video",src:e,allowFullScreen:true})}):null}function L({medias:e,tweetHref:t}){let r=e.filter(i=>i.type==="image"),o=e.filter(i=>i.type==="video"),a=()=>o.length?jsxRuntime.jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:o.map(i=>jsxRuntime.jsx(E,{src:i.url},i.url))}):null,s=()=>r.length?jsxRuntime.jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:r.map(i=>jsxRuntime.jsx(ui.Link,{href:t,target:"_blank",children:jsxRuntime.jsx(S,{src:i.url})},i.url))}):null;return jsxRuntime.jsxs("div",{className:"flex flex-col gap-2",children:[a(),s()]})}function U({url:e,name:t="",size:r=36}){let o=react.useMemo(()=>t?t.slice(0,2):"N/A",[t]);return jsxRuntime.jsx(ui.Skeleton,{className:"flex rounded-full flex-shrink-0",style:{width:r,height:r},isLoaded:!!e,children:jsxRuntime.jsx(ui.Avatar,{size:"md",color:"primary",radius:"full",showFallback:true,name:o,src:e,style:{width:r,height:r}})})}function B({user:e,renderTimestamp:t,renderActions:r}){return jsxRuntime.jsxs("div",{className:"flex items-center justify-between gap-1",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-1",children:[jsxRuntime.jsx(U,{url:e.avatar,name:e.username}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxRuntime.jsxs("div",{className:"flex flex-row items-baseline gap-1",children:[jsxRuntime.jsx("span",{className:"text-foreground font-semibold truncate leading-none",children:e.username}),t]}),jsxRuntime.jsxs(ui.Link,{target:"_blank",underline:"hover",className:"text-default-500 text-sm leading-none",href:utils.twitterUserUrl(e.screenName??e.username),children:["@",e.screenName??e.username]})]})]}),r]})}var N=react.createContext({});var h=react.createContext(null);function O(){let e=react.useContext(N);if(!e)throw new Error("useMediaTrackContext must be used within a MediaTrackProvider");return e}function y(){let{client:e}=O();return e}function Ue(e={}){let t=y();return reactQuery.useMutation({mutationFn:async r=>t.generateMeme(r),...e})}function H(){let e=react.useContext(h);if(!e)throw new Error("useMediaTrackRuntime must be used within a MediaTrackProvider");return e}async function se(e,{media:t,targetLanguage:r,options:o}){return await e.translate(t,r,o)}function _(e={}){let t=y();return reactQuery.useMutation({mutationFn:async r=>se(t,r),...e})}function R(e){let t=/(https?:\/\/[^\s]+|www\.[^\s]+)/gi,r=/#[\w]+/g,o=/\$[A-Za-z][A-Za-z0-9_]*/g,a=[],s;for(;(s=t.exec(e))!==null;)a.push({index:s.index,length:s[0].length,text:s[0],type:"url"});for(;(s=r.exec(e))!==null;){let n=s.index;a.some(m=>n>=m.index&&n<m.index+m.length)||a.push({index:n,length:s[0].length,text:s[0],type:"hashtag"});}for(;(s=o.exec(e))!==null;){let n=s.index;a.some(m=>n>=m.index&&n<m.index+m.length)||a.push({index:n,length:s[0].length,text:s[0],type:"symbol"});}a.sort((n,u)=>n.index-u.index);let i=[],d=0,c=0;return a.forEach(n=>{if(n.index>d&&i.push(e.slice(d,n.index)),n.type==="url"){let u=n.text.startsWith("http")?n.text:`https://${n.text}`;i.push(jsxRuntime.jsx("a",{href:u,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:m=>m.stopPropagation(),children:n.text},c++));}else if(n.type==="hashtag"){let m=`https://x.com/hashtag/${n.text.slice(1)}`;i.push(jsxRuntime.jsx("a",{href:m,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:T=>T.stopPropagation(),children:n.text},c++));}else n.type==="symbol"&&i.push(jsxRuntime.jsx("span",{className:"text-primary",children:n.text},c++));d=n.index+n.length;}),d<e.length&&i.push(e.slice(d)),i.length>0?i:[e]}function W({data:e,embed:t,renderActions:r}){let[o,{toggle:a}]=hooks.useBoolean(false),{t:s,i18n:i}=i18n.useTranslation(),{mutateAsync:d,isPending:c}=_(),[n,u]=react.useState(null),m=react.useCallback(async T=>{if(T.stopPropagation(),a(),!n){let I=await d({media:e,targetLanguage:i.language,options:{sourceTweet:t}}),Me=R(I);u(Me);}},[a,d,e,i.language,n,t]);return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-1 text-xs",children:[jsxRuntime.jsxs("div",{onClick:m,className:"flex items-center gap-0.5 cursor-pointer text-primary hover:text-foreground",children:[jsxRuntime.jsx(ui.TranslateIcon,{width:"14",height:"14"}),s(o?"mediaTrack.tweets.translate.hide":"mediaTrack.tweets.translate.show")]}),r]}),jsxRuntime.jsx("div",{className:ui.cn(!o&&"hidden"),onClick:T=>{T.stopPropagation();},children:o&&jsxRuntime.jsxs("div",{className:"bg-content2 rounded-md p-2 text-default-900 text-sm leading-5",children:[n,c&&jsxRuntime.jsx(ui.Skeleton,{className:"w-full h-4 rounded-md"})]})})]})}function z({isExpanded:e,onToggleExpand:t}){let{t:r}=i18n.useTranslation(),o=()=>e?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(ui.ChevronUpIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",r("mediaTrack.tweets.collapse")]}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(ui.ChevronDownIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",r("mediaTrack.tweets.expand")]});return e===void 0?null:jsxRuntime.jsxs("div",{className:"flex items-center gap-1",children:[jsxRuntime.jsx("div",{className:"w-px h-2.5 bg-line-300"}),jsxRuntime.jsx("button",{onClick:a=>{a.stopPropagation(),t?.(!e);},className:"flex items-center text-default-500 hover:text-foreground text-xs",children:o()})]})}function de({content:e,isExpanded:t=false,onLoad:r}){let o=react.useRef(null),a=react.useMemo(()=>R(e),[e]);return react.useEffect(()=>{let s=o.current;!r||!s||s.scrollHeight>s.clientHeight&&r?.();},[t,r]),jsxRuntime.jsx("div",{ref:o,className:["text-default-900 text-sm leading-5",t?"":"line-clamp-3"].join(" "),onClick:s=>{s.stopPropagation();},children:a})}function p({data:e,headerActions:t,footerActions:r,embed:o=false,indicator:a,children:s}){let[i,d]=react.useState(void 0),c=react.useMemo(()=>o?"bg-default-50 rounded-lg p-3 w-full mx-auto":"bg-default-100 hover:bg-default-200 rounded-lg p-3 w-full mx-auto",[o]),n=react.useMemo(()=>o?e.sourceTweet:e.tweet,[e,o]),u=hooks.useTickAge(n.timestamp);return jsxRuntime.jsxs("div",{className:ui.cn("flex flex-col gap-1.5 cursor-pointer",c),onClick:()=>{window.open(utils.twitterTweetUrl(n.tweetId),"_blank");},children:[jsxRuntime.jsx(B,{user:n.user,renderTimestamp:o?void 0:jsxRuntime.jsx("div",{className:"text-xs text-primary",children:utils.formatAge(u)}),renderActions:t}),a,n.content.text&&jsxRuntime.jsx(de,{content:n.content.text,isExpanded:i,onLoad:()=>d(false)}),n.content.text&&jsxRuntime.jsx(W,{data:e,embed:o,text:n.content.text,renderActions:jsxRuntime.jsx(z,{isExpanded:i,onToggleExpand:d})}),jsxRuntime.jsx("div",{className:ui.cn((!n.content.medias||n.content.medias.length===0)&&"hidden"),children:n.content.medias&&n.content.medias.length>0&&jsxRuntime.jsx(L,{medias:n.content.medias,tweetHref:utils.twitterTweetUrl(n.tweetId)})}),s,r]})}function D({data:e,headerActions:t,footerActions:r}){return jsxRuntime.jsx(p,{data:e,headerActions:t,footerActions:r})}function Q({data:e,headerActions:t,footerActions:r}){let a=!!e.sourceTweet;return jsxRuntime.jsx(p,{data:e,headerActions:t,footerActions:r,children:a?jsxRuntime.jsx(p,{data:e,embed:true}):null})}function Z({data:e,headerActions:t,footerActions:r}){let o=e.sourceTweet,a=!!o,s=react.useMemo(()=>jsxRuntime.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[jsxRuntime.jsx("span",{children:"Replying to"}),a&&jsxRuntime.jsxs(ui.Link,{className:"text-sm",underline:"hover",target:"_blank",href:utils.twitterUserUrl(o.user.screenName??o.user.username),children:["@",o.user.screenName??o.user.username]})]}),[a,o]);return jsxRuntime.jsx(p,{data:e,indicator:s,headerActions:t,footerActions:r,children:a?jsxRuntime.jsx(p,{data:e,embed:true}):null})}function J({data:e,headerActions:t,footerActions:r}){let o=e.sourceTweet,a=!!o,s=react.useMemo(()=>jsxRuntime.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[jsxRuntime.jsx("span",{children:"Retweeted by"}),a&&jsxRuntime.jsxs(ui.Link,{className:"text-sm",underline:"hover",target:"_blank",href:utils.twitterUserUrl(o.user.screenName??o.user.username),children:["@",o.user.screenName??o.user.username]})]}),[a,o]);return jsxRuntime.jsx(p,{data:e,indicator:s,headerActions:t,footerActions:r,children:a?jsxRuntime.jsx(p,{data:e,embed:true}):null})}function K({data:e,headerActions:t,footerActions:r,embed:o=false,children:a,loading:s=false}){if(s||!e)return jsxRuntime.jsx(dt,{embed:o});let i=e.tweet.type;return jsxRuntime.jsx("div",{className:"w-full",children:(()=>{let c={data:e,headerActions:t,footerActions:r,embed:o,children:a};switch(i){case "reply":return jsxRuntime.jsx(Z,{...c});case "retweet":return jsxRuntime.jsx(J,{...c});case "quote":return jsxRuntime.jsx(Q,{...c});default:return jsxRuntime.jsx(D,{...c})}})()})}function dt({embed:e=false}){return jsxRuntime.jsxs("div",{className:["flex flex-col gap-2",e?"bg-default-50 rounded-lg p-3 w-full mx-auto":"bg-default-100 rounded-lg p-3 w-full mx-auto"].join(" "),children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-3",children:[jsxRuntime.jsx(ui.Skeleton,{className:"w-10 h-10 rounded-full"}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-1 flex-1",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-24"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-3 w-16"})]}),jsxRuntime.jsx(ui.Skeleton,{className:"h-3 w-12"})]}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-2",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-full"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-3/4"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-1/2"})]}),jsxRuntime.jsx(ui.Skeleton,{className:"h-48 w-full rounded-lg"}),jsxRuntime.jsxs("div",{className:"flex justify-between items-center pt-2",children:[jsxRuntime.jsxs("div",{className:"flex gap-4",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-16"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-16"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-16"})]}),jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-20"})]})]})}function xe({token:e}){let t=new utils.SafeBigNumber(e.priceChange??"0").isPositive()?"primary":"danger";return jsxRuntime.jsxs(ui.Button,{color:t,variant:"flat",size:"sm",radius:"full",startContent:jsxRuntime.jsx(wt,{token:e}),children:[jsxRuntime.jsx("span",{children:e.symbol}),jsxRuntime.jsx("span",{children:e.priceChange?utils.formatPercent(Number(e.priceChange)/100):"--"})]})}function wt({token:e}){let t=react.useMemo(()=>jsxRuntime.jsx(ui.Image,{className:"w-full h-full",src:e.image,alt:e.chain}),[e.chain,e.image]);return jsxRuntime.jsx(ui.Badge,{className:"w-2.5 h-2.5 p-0 border",size:"sm",content:t,shape:"circle",placement:"bottom-right",children:jsxRuntime.jsx(ui.Avatar,{className:"w-5 h-5",radius:"full",src:e.image})})}function Y({data:e,loading:t,setIsPaused:r,customHeaderActions:o,customFooterActions:a}){let s=react.useCallback(i=>jsxRuntime.jsxs("div",{className:"flex gap-2.5 justify-between",children:[i.token&&jsxRuntime.jsx(xe,{token:i.token}),a?.(i)]}),[a]);return jsxRuntime.jsx("div",{className:"flex flex-col gap-2.5",onMouseEnter:()=>r(true),onMouseLeave:()=>r(false),children:e.map(i=>jsxRuntime.jsx(K,{data:i,headerActions:o?.(i),footerActions:s(i),loading:t},i.id))})}function we(){return jsxRuntime.jsxs("div",{className:"flex flex-col gap-2 bg-default-100 rounded-lg p-3 w-full mx-auto",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-3",children:[jsxRuntime.jsx(ui.Skeleton,{className:"w-10 h-10 rounded-full"}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-1 flex-1",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-40 rounded-md"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-3 w-32 rounded-md"})]})]}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-2",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-full rounded-md"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-3/4 rounded-md"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-1/2 rounded-md"})]}),jsxRuntime.jsx(ui.Skeleton,{className:"h-48 w-full rounded-lg"})]})}function j({count:e=3}){return jsxRuntime.jsx("div",{className:"flex flex-col gap-2",children:Array.from({length:e}).map((t,r)=>jsxRuntime.jsx(we,{},r))})}var te=()=>{let[e,t]=react.useState([]),[r,o]=react.useState(true),[a,s]=react.useState(false),i=H(),d=react.useCallback(c=>{t(n=>{let u=n.findIndex(T=>T.id===c.id),m;if(u>=0)m=n.map((T,I)=>I===u?c:T);else {if(a)return n;m=[c,...n];}return m.slice(0,30)}),o(false);},[a]);return react.useEffect(()=>{let c=i.subscribe("x-monitor-basic",d),n=i.subscribe("x-monitor-token",d);return ()=>{c.unsubscribe(),n.unsubscribe();}},[i,d]),{medias:e,loading:r,isPaused:a,setIsPaused:s}};function Nt({onPauseChange:e,customHeaderActions:t,customFooterActions:r}){let{medias:o,loading:a,isPaused:s,setIsPaused:i}=te();return react.useEffect(()=>{e?.(s);},[s,e]),a?jsxRuntime.jsx(j,{count:3}):jsxRuntime.jsx(Y,{data:o,loading:a,setIsPaused:i,customHeaderActions:t,customFooterActions:r})}function re(){let e=0,t=false,r=null,o=new Map;return {get generation(){return e},connect(){e+=1,t=true;},disconnect(){t=false;},setLocaleTransform(a){r=a;},subscribe(a,s){let i=o.get(a);i||(i=new Set,o.set(a,i)),i.add(s);let d=false;return {unsubscribe(){if(d)return;d=true;let c=o.get(a);c?.delete(s),c&&c.size===0&&o.delete(a);}}},publish(a,s){if(!t)return;let i=r?r(s):s;o.get(a)?.forEach(d=>d(i));}}}function Pt({client:e,children:t}){let r=react.useMemo(()=>re(),[]);return jsxRuntime.jsx(N.Provider,{value:{client:e},children:jsxRuntime.jsxs(h.Provider,{value:r,children:[jsxRuntime.jsx(At,{client:e}),t]})})}function At({client:e}){let t=react.useContext(h);return react.useEffect(()=>{if(!t)return;t.connect();let r=e.subscribeTweetMedia({callback:a=>t.publish("x-monitor-basic",a)}),o=e.subscribeTweetMediaToken({callback:a=>t.publish("x-monitor-token",a)});return ()=>{r.unsubscribe(),o.unsubscribe(),t.disconnect();}},[e,t]),null}
|
|
2
|
+
exports.MediaImage=S;exports.MediaTrackContext=N;exports.MediaTrackProvider=Pt;exports.MediaTrackRuntimeContext=h;exports.MediaVideo=E;exports.Medias=L;exports.TextExpand=z;exports.Translate=W;exports.TweetItem=K;exports.TweetOriginal=D;exports.TweetQuote=Q;exports.TweetReply=Z;exports.TweetRetweet=J;exports.TweetSkeleton=we;exports.TweetSkeletonList=j;exports.TweetSource=p;exports.Tweets=Y;exports.TweetsWidget=Nt;exports.UserAvatar=U;exports.UserInfo=B;exports.createMediaTrackRuntime=re;exports.translateTweetMedia=se;exports.useGenerateTweetMediaMemeMutation=Ue;exports.useMediaTrackClient=y;exports.useMediaTrackContext=O;exports.useMediaTrackRuntime=H;exports.useTranslateTweetMediaMutation=_;exports.useTweets=te;//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/tweets/tweet/media/media-image.tsx","../src/components/tweets/tweet/media/media-video.tsx","../src/components/tweets/tweet/media/medias.tsx","../src/components/tweets/tweet/user/user-avatar.tsx","../src/components/tweets/tweet/user/user-info.tsx","../src/context/MediaTrackContext.ts","../src/hooks/useMediaTrackContext.ts","../src/hooks/useMediaTrackClient.ts","../src/hooks/useGenerateTweetMediaMemeMutation.ts","../src/hooks/useTranslateTweetMediaQuery.ts","../src/utils/parseText.tsx","../src/components/tweets/tweet/tools/translate.tsx","../src/components/tweets/tweet/tools/text-expand.tsx","../src/components/tweets/tweet/content/index.tsx","../src/components/tweets/tweet/tweet-source.tsx","../src/components/tweets/tweet/tweet-original.tsx","../src/components/tweets/tweet/tweet-quote.tsx","../src/components/tweets/tweet/tweet-reply.tsx","../src/components/tweets/tweet/tweet-retweet.tsx","../src/components/tweets/tweet/tweet-item.tsx","../src/components/tweets/tweet/tools/tweet-token-button.tsx","../src/components/tweets/tweets.ui.tsx","../src/components/tweets/tweet/tweet-skeleton.tsx","../src/components/tweets/tweets.script.ts","../src/components/tweets/tweets.widget.tsx","../src/providers/MediaTrackProvider.tsx"],"names":["MediaImage","src","isLoaded","setTrue","useBoolean","jsx","Skeleton","MediaVideo","Medias","medias","tweetHref","images","media","videos","renderVideos","video","renderImages","image","Link","jsxs","UserAvatar","url","name","size","fallbackName","useMemo","Avatar","UserInfo","user","renderTimestamp","renderActions","twitterUserUrl","MediaTrackContext","createContext","useMediaTrackContext","context","useContext","useMediaTrackClient","client","useGenerateTweetMediaMemeMutation","options","useMutation","params","translateTweetMedia","targetLanguage","useTranslateTweetMediaMutation","parseText","text","urlRegex","hashtagRegex","symbolRegex","matches","match","matchIndex","m","a","b","parts","lastIndex","key","item","e","hashtagUrl","Translate","data","embed","isTranslate","toggle","t","i18n","useTranslation","isTranslating","translatedText","setTranslatedText","useState","handleTranslate","useCallback","parsedText","Fragment","TranslateIcon","cn","TextExpand","isExpanded","onToggleExpand","renderExpand","ChevronUpIcon","ChevronDownIcon","Content","content","onLoad","ref","useRef","parsedContent","useEffect","current","TweetSource","headerActions","footerActions","indicator","children","setIsExpanded","containerClass","tweet","age","useTickAge","twitterTweetUrl","formatAge","TweetOriginal","TweetQuote","hasSource","TweetReply","sourceTweet","TweetRetweet","TweetItem","loading","TweetSkeleton","tweetType","commonProps","TweetTokenButton","token","color","SafeBigNumber","Button","TweetTokenIcon","formatPercent","ChainIcon","Image","Badge","Tweets","setIsPaused","customHeaderActions","customFooterActions","TweetSkeletonList","count","_","index","useTweets","setMedias","setLoading","isPaused","handleMedia","prevMedias","idx","it","newMedias","subTweet","subTweetToken","TweetsWidget","onPauseChange","MediaTrackProvider"],"mappings":"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","file":"index.js","sourcesContent":["import { useBoolean } from \"@liberfi.io/hooks\";\nimport { Skeleton } from \"@liberfi.io/ui\";\n\ntype Props = {\n src: string;\n};\n\n// ------------------------------------------------------------\nexport function MediaImage({ src }: Props) {\n const [isLoaded, { setTrue }] = useBoolean(false);\n if (!src) return null;\n\n return (\n <Skeleton isLoaded={isLoaded} className=\"w-full h-auto\">\n <img\n src={src}\n className=\"w-full h-full object-cover aspect-video\"\n onLoad={() => {\n setTrue();\n }}\n />\n </Skeleton>\n );\n}\n","type Props = {\n src: string;\n};\n\n// ------------------------------------------------------------\nexport function MediaVideo({ src }: Props) {\n if (!src) return null;\n\n return (\n <div className=\"w-full h-full overflow-hidden rounded-md mt-2\">\n <iframe\n className=\"w-full h-full aspect-video\"\n src={src}\n allowFullScreen\n />\n </div>\n );\n}\n","import { Link } from \"@liberfi.io/ui\";\nimport { TweetContentMedia } from \"../../../../types\";\nimport { MediaImage } from \"./media-image\";\nimport { MediaVideo } from \"./media-video\";\n\ntype Props = {\n medias: Array<TweetContentMedia>;\n tweetHref: string;\n};\n\nexport function Medias({ medias, tweetHref }: Props) {\n const images = medias.filter((media) => media.type === \"image\");\n const videos = medias.filter((media) => media.type === \"video\");\n\n const renderVideos = () => {\n if (!videos.length) return null;\n return (\n <div className={`grid grid-cols-1 gap-[1px] overflow-hidden rounded-md`}>\n {videos.map((video) => (\n <MediaVideo key={video.url} src={video.url} />\n ))}\n </div>\n );\n };\n\n const renderImages = () => {\n if (!images.length) return null;\n return (\n <div className={`grid grid-cols-1 gap-[1px] overflow-hidden rounded-md`}>\n {images.map((image) => (\n <Link key={image.url} href={tweetHref} target=\"_blank\">\n <MediaImage src={image.url} />\n </Link>\n ))}\n </div>\n );\n };\n\n return (\n <div className=\"flex flex-col gap-2\">\n {renderVideos()}\n {renderImages()}\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { Avatar, Skeleton } from \"@liberfi.io/ui\";\n\ntype Props = {\n url?: string;\n name?: string;\n size?: number;\n};\n\nexport function UserAvatar({ url, name = \"\", size = 36 }: Props) {\n const fallbackName = useMemo(() => (name ? name.slice(0, 2) : \"N/A\"), [name]);\n\n return (\n <Skeleton\n className=\"flex rounded-full flex-shrink-0\"\n style={{ width: size, height: size }}\n isLoaded={!!url}\n >\n <Avatar\n size=\"md\"\n color=\"primary\"\n radius=\"full\"\n showFallback\n name={fallbackName}\n src={url}\n style={{ width: size, height: size }}\n />\n </Skeleton>\n );\n}\n","import React from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetUser } from \"../../../../types\";\nimport { UserAvatar } from \"./user-avatar\";\n\ntype Props = {\n user: TweetUser;\n renderTimestamp?: React.ReactNode;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function UserInfo({ user, renderTimestamp, renderActions }: Props) {\n return (\n <div className=\"flex items-center justify-between gap-1\">\n <div className=\"flex items-center gap-1\">\n <UserAvatar url={user.avatar} name={user.username} />\n <div className=\"flex flex-col gap-0.5\">\n <div className=\"flex flex-row items-baseline gap-1\">\n <span className=\"text-foreground font-semibold truncate leading-none\">\n {user.username}\n </span>\n {renderTimestamp}\n </div>\n <Link\n target=\"_blank\"\n underline=\"hover\"\n className=\"text-default-500 text-sm leading-none\"\n href={twitterUserUrl(user.screenName ?? user.username)}\n >\n @{user.screenName ?? user.username}\n </Link>\n </div>\n </div>\n {renderActions}\n </div>\n );\n}\n","import { createContext } from \"react\";\nimport { IMediaTrackClient } from \"../types\";\n\nexport interface MediaTrackContextValue {\n client: IMediaTrackClient;\n}\n\nexport const MediaTrackContext = createContext<MediaTrackContextValue>(\n {} as MediaTrackContextValue,\n);\n","import { useContext } from \"react\";\nimport { MediaTrackContext } from \"../context\";\n\nexport function useMediaTrackContext() {\n const context = useContext(MediaTrackContext);\n if (!context) {\n throw new Error(\n \"useMediaTrackContext must be used within a MediaTrackProvider\",\n );\n }\n return context;\n}\n","import { useMediaTrackContext } from \"./useMediaTrackContext\";\n\nexport function useMediaTrackClient() {\n const { client } = useMediaTrackContext();\n return client;\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport { GeneratedMemeInfo, TweetMedia } from \"../types\";\nimport { useMediaTrackClient } from \"./useMediaTrackClient\";\n\nexport function useGenerateTweetMediaMemeMutation(\n options: Omit<\n UseMutationOptions<GeneratedMemeInfo, Error, TweetMedia, string[]>,\n \"mutationFn\"\n > = {},\n) {\n const client = useMediaTrackClient();\n return useMutation({\n mutationFn: async (params: TweetMedia) => client.generateMeme(params),\n ...options,\n });\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport { LocaleCode } from \"@liberfi.io/i18n\";\nimport { IMediaTrackClient, TweetMedia } from \"../types\";\nimport { useMediaTrackClient } from \"./useMediaTrackClient\";\n\nexport interface UseTranslateTweetMediaParams {\n media: TweetMedia;\n targetLanguage: LocaleCode;\n options?: {\n sourceLanguage?: LocaleCode;\n sourceTweet?: boolean;\n };\n}\n\nexport async function translateTweetMedia(\n client: IMediaTrackClient,\n { media, targetLanguage, options }: UseTranslateTweetMediaParams,\n) {\n return await client.translate(media, targetLanguage, options);\n}\n\nexport function useTranslateTweetMediaMutation(\n options: Omit<\n UseMutationOptions<string, Error, UseTranslateTweetMediaParams>,\n \"mutationFn\"\n > = {},\n) {\n const client = useMediaTrackClient();\n return useMutation({\n mutationFn: async (params: UseTranslateTweetMediaParams) =>\n translateTweetMedia(client, params),\n ...options,\n });\n}\n","interface MatchItem {\n index: number;\n length: number;\n text: string;\n type: \"url\" | \"hashtag\" | \"symbol\";\n}\n\nexport function parseText(text: string): (string | React.ReactElement)[] {\n const urlRegex = /(https?:\\/\\/[^\\s]+|www\\.[^\\s]+)/gi;\n const hashtagRegex = /#[\\w]+/g;\n const symbolRegex = /\\$[A-Za-z][A-Za-z0-9_]*/g;\n\n const matches: MatchItem[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = urlRegex.exec(text)) !== null) {\n matches.push({\n index: match.index,\n length: match[0].length,\n text: match[0],\n type: \"url\",\n });\n }\n\n while ((match = hashtagRegex.exec(text)) !== null) {\n const matchIndex = match.index;\n const overlaps = matches.some(\n (m) => matchIndex >= m.index && matchIndex < m.index + m.length,\n );\n if (!overlaps) {\n matches.push({\n index: matchIndex,\n length: match[0].length,\n text: match[0],\n type: \"hashtag\",\n });\n }\n }\n\n while ((match = symbolRegex.exec(text)) !== null) {\n const matchIndex = match.index;\n const overlaps = matches.some(\n (m) => matchIndex >= m.index && matchIndex < m.index + m.length,\n );\n if (!overlaps) {\n matches.push({\n index: matchIndex,\n length: match[0].length,\n text: match[0],\n type: \"symbol\",\n });\n }\n }\n\n matches.sort((a, b) => a.index - b.index);\n\n const parts: (string | React.ReactElement)[] = [];\n let lastIndex = 0;\n let key = 0;\n\n matches.forEach((item) => {\n if (item.index > lastIndex) {\n parts.push(text.slice(lastIndex, item.index));\n }\n\n if (item.type === \"url\") {\n const url = item.text.startsWith(\"http\")\n ? item.text\n : `https://${item.text}`;\n parts.push(\n <a\n key={key++}\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline\"\n onClick={(e) => e.stopPropagation()}\n >\n {item.text}\n </a>,\n );\n } else if (item.type === \"hashtag\") {\n const hashtag = item.text.slice(1); // 移除 #\n const hashtagUrl = `https://x.com/hashtag/${hashtag}`;\n parts.push(\n <a\n key={key++}\n href={hashtagUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline\"\n onClick={(e) => e.stopPropagation()}\n >\n {item.text}\n </a>,\n );\n } else if (item.type === \"symbol\") {\n parts.push(\n <span key={key++} className=\"text-primary\">\n {item.text}\n </span>,\n );\n }\n\n lastIndex = item.index + item.length;\n });\n\n if (lastIndex < text.length) {\n parts.push(text.slice(lastIndex));\n }\n\n return parts.length > 0 ? parts : [text];\n}\n","import React, { MouseEvent, useCallback, useState } from \"react\";\nimport { useBoolean } from \"@liberfi.io/hooks\";\nimport { LocaleCode, useTranslation } from \"@liberfi.io/i18n\";\nimport { cn, Skeleton, TranslateIcon } from \"@liberfi.io/ui\";\nimport { useTranslateTweetMediaMutation } from \"../../../../hooks\";\nimport { TweetMedia } from \"../../../../types\";\nimport { parseText } from \"../../../../utils\";\n\ntype Props = {\n data: TweetMedia;\n embed?: boolean;\n text: string;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function Translate({ data, embed, renderActions }: Props) {\n const [isTranslate, { toggle }] = useBoolean(false);\n\n const { t, i18n } = useTranslation();\n\n const { mutateAsync: translateTweetMedia, isPending: isTranslating } =\n useTranslateTweetMediaMutation();\n\n const [translatedText, setTranslatedText] = useState<\n (string | React.ReactElement)[] | null\n >(null);\n\n const handleTranslate = useCallback(\n async (e: MouseEvent<HTMLDivElement>) => {\n e.stopPropagation();\n toggle();\n if (!translatedText) {\n const text = await translateTweetMedia({\n media: data,\n targetLanguage: i18n.language as LocaleCode,\n options: {\n sourceTweet: embed,\n },\n });\n const parsedText = parseText(text);\n setTranslatedText(parsedText);\n }\n },\n [toggle, translateTweetMedia, data, i18n.language, translatedText],\n );\n\n return (\n <>\n <div className=\"flex items-center gap-1 text-xs\">\n <div\n onClick={handleTranslate}\n className=\"flex items-center gap-0.5 cursor-pointer text-primary hover:text-foreground\"\n >\n <TranslateIcon width=\"14\" height=\"14\" />\n {isTranslate\n ? t(\"mediaTrack.tweets.translate.hide\")\n : t(\"mediaTrack.tweets.translate.show\")}\n </div>\n {renderActions}\n </div>\n <div\n className={cn(!isTranslate && \"hidden\")}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n {isTranslate && (\n <div className=\"bg-content2 rounded-md p-2 text-default-900 text-sm leading-5\">\n {translatedText}\n {isTranslating && <Skeleton className=\"w-full h-4 rounded-md\" />}\n </div>\n )}\n </div>\n </>\n );\n}\n","import { useTranslation } from \"@liberfi.io/i18n\";\nimport { ChevronDownIcon, ChevronUpIcon } from \"@liberfi.io/ui\";\n\ntype Props = {\n isExpanded?: boolean;\n onToggleExpand?: (expanded: boolean) => void;\n};\n\nexport function TextExpand({ isExpanded, onToggleExpand }: Props) {\n const { t } = useTranslation();\n const renderExpand = () => {\n if (isExpanded) {\n return (\n <>\n <ChevronUpIcon\n className=\"border border-current\"\n width=\"12\"\n height=\"12\"\n />\n {t(\"mediaTrack.tweets.collapse\")}\n </>\n );\n }\n\n return (\n <>\n <ChevronDownIcon\n className=\"border border-current\"\n width=\"12\"\n height=\"12\"\n />\n {t(\"mediaTrack.tweets.expand\")}\n </>\n );\n };\n\n if (isExpanded === undefined) return null;\n\n return (\n <div className=\"flex items-center gap-1\">\n <div className=\"w-px h-2.5 bg-line-300\" />\n <button\n onClick={(e) => {\n e.stopPropagation();\n onToggleExpand?.(!isExpanded);\n }}\n className=\"flex items-center text-default-500 hover:text-foreground text-xs\"\n >\n {renderExpand()}\n </button>\n </div>\n );\n}\n","import React, { useEffect, useMemo, useRef } from \"react\";\nimport { parseText } from \"../../../../utils\";\n\ntype Props = {\n content: string;\n isExpanded?: boolean;\n onLoad?: () => void;\n};\n\n// ------------------------------------------------------------\nexport function Content({ content, isExpanded = false, onLoad }: Props) {\n const ref = useRef<HTMLDivElement>(null);\n\n const parsedContent = useMemo(() => parseText(content), [content]);\n\n useEffect(() => {\n const current = ref.current;\n if (!onLoad || !current) return;\n if (current.scrollHeight > current.clientHeight) {\n onLoad?.();\n }\n }, [isExpanded]);\n\n return (\n <div\n ref={ref}\n className={[\n \"text-default-900 text-sm leading-5\",\n !isExpanded ? \"line-clamp-3\" : \"\",\n ].join(\" \")}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n {parsedContent}\n </div>\n );\n}\n","import React, { useMemo, useState } from \"react\";\nimport { useTickAge } from \"@liberfi.io/hooks\";\nimport { cn } from \"@liberfi.io/ui\";\nimport { formatAge, twitterTweetUrl } from \"@liberfi.io/utils\";\nimport { Tweet, TweetMedia } from \"../../../types\";\nimport { Content } from \"./content\";\nimport { Medias } from \"./media\";\nimport { Translate, TextExpand } from \"./tools\";\nimport { UserInfo } from \"./user\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n embed?: boolean;\n indicator?: React.ReactNode;\n children?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetSource({\n data,\n headerActions,\n footerActions,\n embed = false,\n indicator,\n children,\n}: Props) {\n const [isExpanded, setIsExpanded] = useState<boolean | undefined>(undefined);\n\n const containerClass = useMemo(() => {\n return embed\n ? \"bg-default-50 rounded-lg p-3 w-full mx-auto\"\n : \"bg-default-100 hover:bg-default-200 rounded-lg p-3 w-full mx-auto\";\n }, [embed]);\n\n const tweet = useMemo(\n () => (embed ? data.sourceTweet! : data.tweet),\n [data, embed],\n );\n\n const age = useTickAge((tweet as Tweet).timestamp);\n\n return (\n <div\n className={cn(\"flex flex-col gap-1.5 cursor-pointer\", containerClass)}\n onClick={() => {\n window.open(twitterTweetUrl(tweet.tweetId), \"_blank\");\n }}\n >\n {/* -------- USER INFO -------- */}\n <UserInfo\n user={tweet.user}\n renderTimestamp={\n embed ? undefined : (\n <div className=\"text-xs text-primary\">{formatAge(age)}</div>\n )\n }\n renderActions={headerActions}\n />\n\n {/* -------- MESSAGE TYPE INDICATOR -------- */}\n {indicator}\n\n {/* -------- CONTENT -------- */}\n {tweet.content.text && (\n <Content\n content={tweet.content.text}\n isExpanded={isExpanded}\n onLoad={() => setIsExpanded(false)}\n />\n )}\n\n {/* -------- TOOLS -------- */}\n {tweet.content.text && (\n <Translate\n data={data}\n embed={embed}\n text={tweet.content.text}\n renderActions={\n <TextExpand\n isExpanded={isExpanded}\n onToggleExpand={setIsExpanded}\n />\n }\n />\n )}\n\n {/* -------- MEDIA -------- */}\n <div\n className={cn(\n (!tweet.content.medias || tweet.content.medias.length === 0) &&\n \"hidden\",\n )}\n >\n {tweet.content.medias && tweet.content.medias.length > 0 && (\n <Medias\n medias={tweet.content.medias}\n tweetHref={twitterTweetUrl(tweet.tweetId)}\n />\n )}\n </div>\n\n {/* -------- CHILDREN -------- */}\n {children}\n\n {/* -------- Custom ACTIONS -------- */}\n {footerActions}\n </div>\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetOriginal({ data, headerActions, footerActions }: Props) {\n return (\n <TweetSource\n data={data}\n headerActions={headerActions}\n footerActions={footerActions}\n />\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetQuote({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n return (\n <TweetSource\n data={data}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetReply({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n const indicator = useMemo(\n () => (\n <div className=\"flex items-center gap-2 text-sm\">\n <span>Replying to</span>\n {hasSource && (\n <Link\n className=\"text-sm\"\n underline=\"hover\"\n target=\"_blank\"\n href={twitterUserUrl(\n sourceTweet.user.screenName ?? sourceTweet.user.username,\n )}\n >\n @{sourceTweet.user.screenName ?? sourceTweet.user.username}\n </Link>\n )}\n </div>\n ),\n [hasSource, sourceTweet],\n );\n\n return (\n <TweetSource\n data={data}\n indicator={indicator}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetRetweet({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n const indicator = useMemo(\n () => (\n <div className=\"flex items-center gap-2 text-sm\">\n <span>Retweeted by</span>\n {hasSource && (\n <Link\n className=\"text-sm\"\n underline=\"hover\"\n target=\"_blank\"\n href={twitterUserUrl(\n sourceTweet.user.screenName ?? sourceTweet.user.username,\n )}\n >\n @{sourceTweet.user.screenName ?? sourceTweet.user.username}\n </Link>\n )}\n </div>\n ),\n [hasSource, sourceTweet],\n );\n\n return (\n <TweetSource\n data={data}\n indicator={indicator}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React from \"react\";\nimport { Skeleton } from \"@liberfi.io/ui\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetOriginal } from \"./tweet-original\";\nimport { TweetQuote } from \"./tweet-quote\";\nimport { TweetReply } from \"./tweet-reply\";\nimport { TweetRetweet } from \"./tweet-retweet\";\n\ntype Props = {\n data?: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n embed?: boolean;\n children?: React.ReactNode;\n loading?: boolean;\n};\n\n// ------------------------------------------------------------\nexport function TweetItem({\n data,\n headerActions,\n footerActions,\n embed = false,\n children,\n loading = false,\n}: Props) {\n if (loading || !data) {\n return <TweetSkeleton embed={embed} />;\n }\n\n const tweetType = data.tweet.type;\n\n // Render appropriate component based on tweet type\n const renderTweetComponent = () => {\n const commonProps = {\n data,\n headerActions,\n footerActions,\n embed,\n children,\n };\n\n switch (tweetType) {\n case \"reply\":\n return <TweetReply {...commonProps} />;\n case \"retweet\":\n return <TweetRetweet {...commonProps} />;\n case \"quote\":\n return <TweetQuote {...commonProps} />;\n default: // \"original\"\n return <TweetOriginal {...commonProps} />;\n }\n };\n\n return <div className=\"w-full\">{renderTweetComponent()}</div>;\n}\n\n// ------------------------------------------------------------\nfunction TweetSkeleton({ embed = false }: { embed?: boolean }) {\n const containerClass = embed\n ? \"bg-default-50 rounded-lg p-3 w-full mx-auto\"\n : \"bg-default-100 rounded-lg p-3 w-full mx-auto\";\n\n return (\n <div className={[\"flex flex-col gap-2\", containerClass].join(\" \")}>\n {/* User Info Skeleton */}\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"w-10 h-10 rounded-full\" />\n <div className=\"flex flex-col gap-1 flex-1\">\n <Skeleton className=\"h-4 w-24\" />\n <Skeleton className=\"h-3 w-16\" />\n </div>\n <Skeleton className=\"h-3 w-12\" />\n </div>\n\n {/* Content Skeleton */}\n <div className=\"flex flex-col gap-2\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-4 w-1/2\" />\n </div>\n\n {/* Media Skeleton */}\n <Skeleton className=\"h-48 w-full rounded-lg\" />\n\n {/* Actions Skeleton */}\n <div className=\"flex justify-between items-center pt-2\">\n <div className=\"flex gap-4\">\n <Skeleton className=\"h-6 w-16\" />\n <Skeleton className=\"h-6 w-16\" />\n <Skeleton className=\"h-6 w-16\" />\n </div>\n <Skeleton className=\"h-6 w-20\" />\n </div>\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { Avatar, Badge, Button, Image } from \"@liberfi.io/ui\";\nimport { formatPercent, SafeBigNumber } from \"@liberfi.io/utils\";\nimport { MediaToken } from \"../../../../types\";\n\ntype Props = {\n token: MediaToken;\n};\n\nexport function TweetTokenButton({ token }: Props) {\n const color = new SafeBigNumber(token.priceChange ?? \"0\").isPositive()\n ? \"primary\"\n : \"danger\";\n\n return (\n <Button\n color={color}\n variant=\"flat\"\n size=\"sm\"\n radius=\"full\"\n startContent={<TweetTokenIcon token={token} />}\n >\n <span>{token.symbol}</span>\n <span>\n {token.priceChange\n ? formatPercent(Number(token.priceChange) / 100)\n : \"--\"}\n </span>\n </Button>\n );\n}\n\nexport function TweetTokenIcon({ token }: Props) {\n const ChainIcon = useMemo(() => {\n return (\n <Image className=\"w-full h-full\" src={token.image} alt={token.chain} />\n );\n }, [token.chain]);\n\n return (\n <Badge\n className=\"w-2.5 h-2.5 p-0 border\"\n size=\"sm\"\n content={ChainIcon}\n shape=\"circle\"\n placement=\"bottom-right\"\n >\n <Avatar className=\"w-5 h-5\" radius=\"full\" src={token.image} />\n </Badge>\n );\n}\n","import { useCallback } from \"react\";\nimport { TweetMedia } from \"../../types\";\nimport { TweetTokenButton } from \"./tweet/tools/tweet-token-button\";\n// import { TweetTradeButton } from \"./tweet/tools/tweet-trade-button\";\nimport { TweetItem } from \"./tweet/tweet-item\";\n\ntype TweetsProps = {\n data: Array<TweetMedia>;\n loading: boolean;\n setIsPaused: (paused: boolean) => void;\n customHeaderActions?: (item: TweetMedia) => React.ReactNode;\n customFooterActions?: (item: TweetMedia) => React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function Tweets({\n data,\n loading,\n setIsPaused,\n customHeaderActions,\n customFooterActions,\n}: TweetsProps) {\n const footerActions = useCallback(\n (item: TweetMedia) => (\n <div className=\"flex gap-2.5 justify-between\">\n {item.token && <TweetTokenButton token={item.token} />}\n {customFooterActions?.(item)}\n {/* {item.token && <TweetTradeButton token={item.token} />} */}\n </div>\n ),\n [customFooterActions],\n );\n\n return (\n <div\n className=\"flex flex-col gap-2.5\"\n onMouseEnter={() => setIsPaused(true)}\n onMouseLeave={() => setIsPaused(false)}\n >\n {data.map((item: TweetMedia) => (\n <TweetItem\n key={item.id}\n data={item}\n headerActions={customHeaderActions?.(item)}\n footerActions={footerActions(item)}\n loading={loading}\n />\n ))}\n </div>\n );\n}\n","import { Skeleton } from \"@liberfi.io/ui\";\n\n// ------------------------------------------------------------\nexport function TweetSkeleton() {\n return (\n <div className=\"flex flex-col gap-2 bg-default-100 rounded-lg p-3 w-full mx-auto\">\n {/* User Info Skeleton */}\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"w-10 h-10 rounded-full\" />\n <div className=\"flex flex-col gap-1 flex-1\">\n <Skeleton className=\"h-4 w-40 rounded-md\" />\n <Skeleton className=\"h-3 w-32 rounded-md\" />\n </div>\n </div>\n\n {/* Content Skeleton */}\n <div className=\"flex flex-col gap-2\">\n <Skeleton className=\"h-4 w-full rounded-md\" />\n <Skeleton className=\"h-4 w-3/4 rounded-md\" />\n <Skeleton className=\"h-4 w-1/2 rounded-md\" />\n </div>\n\n {/* Media Skeleton */}\n <Skeleton className=\"h-48 w-full rounded-lg\" />\n </div>\n );\n}\n\nexport function TweetSkeletonList({ count = 3 }: { count: number }) {\n return (\n <div className=\"flex flex-col gap-2\">\n {Array.from({ length: count }).map((_, index) => (\n <TweetSkeleton key={index} />\n ))}\n </div>\n );\n}\n","import { useCallback, useEffect, useState } from \"react\";\nimport { useMediaTrackClient } from \"../../hooks\";\nimport { TweetMedia } from \"../../types\";\n\nexport const useTweets = () => {\n const [medias, setMedias] = useState<Array<TweetMedia>>([]);\n const [loading, setLoading] = useState(true);\n const [isPaused, setIsPaused] = useState(false);\n\n const client = useMediaTrackClient();\n\n const handleMedia = useCallback(\n (media: TweetMedia) => {\n setMedias((prevMedias) => {\n const idx = prevMedias.findIndex((it) => it.id === media.id);\n let newMedias: Array<TweetMedia>;\n\n if (idx >= 0) {\n newMedias = prevMedias.map((item, index) =>\n index === idx ? media : item,\n );\n } else {\n if (isPaused) {\n return prevMedias;\n }\n newMedias = [media, ...prevMedias];\n }\n\n return newMedias.slice(0, 30);\n });\n setLoading(false);\n },\n [isPaused],\n );\n\n useEffect(() => {\n const subTweet = client.subscribeTweetMedia({ callback: handleMedia });\n const subTweetToken = client.subscribeTweetMediaToken({\n callback: handleMedia,\n });\n return () => {\n subTweet.unsubscribe();\n subTweetToken.unsubscribe();\n };\n }, [client, handleMedia]);\n\n return { medias, loading, isPaused, setIsPaused };\n};\n","import { useEffect } from \"react\";\nimport { TweetMedia } from \"../../types\";\nimport { TweetSkeletonList } from \"./tweet/tweet-skeleton\";\nimport { useTweets } from \"./tweets.script\";\nimport { Tweets } from \"./tweets.ui\";\n\n// ------------------------------------------------------------\nexport type TweetsWidgetProps = {\n onPauseChange?: (paused: boolean) => void;\n customHeaderActions?: (item: TweetMedia) => React.ReactNode;\n customFooterActions?: (item: TweetMedia) => React.ReactNode;\n};\n\nexport function TweetsWidget({\n onPauseChange,\n customHeaderActions,\n customFooterActions,\n}: TweetsWidgetProps) {\n const { medias, loading, isPaused, setIsPaused } = useTweets();\n\n useEffect(() => {\n onPauseChange?.(isPaused);\n }, [isPaused, onPauseChange]);\n\n if (loading) {\n return <TweetSkeletonList count={3} />;\n }\n\n return (\n <Tweets\n data={medias}\n loading={loading}\n setIsPaused={setIsPaused}\n customHeaderActions={customHeaderActions}\n customFooterActions={customFooterActions}\n />\n );\n}\n","import { PropsWithChildren } from \"react\";\nimport { MediaTrackContext } from \"../context\";\nimport { IMediaTrackClient } from \"../types\";\n\nexport type MediaTrackProviderProps = PropsWithChildren<{\n client: IMediaTrackClient;\n}>;\n\nexport function MediaTrackProvider({\n client,\n children,\n}: MediaTrackProviderProps) {\n return (\n <MediaTrackContext.Provider value={{ client }}>\n {children}\n </MediaTrackContext.Provider>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/tweets/tweet/media/media-image.tsx","../src/components/tweets/tweet/media/media-video.tsx","../src/components/tweets/tweet/media/medias.tsx","../src/components/tweets/tweet/user/user-avatar.tsx","../src/components/tweets/tweet/user/user-info.tsx","../src/context/MediaTrackContext.ts","../src/context/MediaTrackRuntimeContext.ts","../src/hooks/useMediaTrackContext.ts","../src/hooks/useMediaTrackClient.ts","../src/hooks/useGenerateTweetMediaMemeMutation.ts","../src/hooks/useMediaTrackRuntime.ts","../src/hooks/useTranslateTweetMediaQuery.ts","../src/utils/parseText.tsx","../src/components/tweets/tweet/tools/translate.tsx","../src/components/tweets/tweet/tools/text-expand.tsx","../src/components/tweets/tweet/content/index.tsx","../src/components/tweets/tweet/tweet-source.tsx","../src/components/tweets/tweet/tweet-original.tsx","../src/components/tweets/tweet/tweet-quote.tsx","../src/components/tweets/tweet/tweet-reply.tsx","../src/components/tweets/tweet/tweet-retweet.tsx","../src/components/tweets/tweet/tweet-item.tsx","../src/components/tweets/tweet/tools/tweet-token-button.tsx","../src/components/tweets/tweets.ui.tsx","../src/components/tweets/tweet/tweet-skeleton.tsx","../src/components/tweets/tweets.script.ts","../src/components/tweets/tweets.widget.tsx","../src/runtime/media-track-runtime.ts","../src/providers/MediaTrackProvider.tsx"],"names":["MediaImage","src","isLoaded","setTrue","useBoolean","jsx","Skeleton","MediaVideo","Medias","medias","tweetHref","images","media","videos","renderVideos","video","renderImages","image","Link","jsxs","UserAvatar","url","name","size","fallbackName","useMemo","Avatar","UserInfo","user","renderTimestamp","renderActions","twitterUserUrl","MediaTrackContext","createContext","MediaTrackRuntimeContext","useMediaTrackContext","context","useContext","useMediaTrackClient","client","useGenerateTweetMediaMemeMutation","options","useMutation","params","useMediaTrackRuntime","runtime","translateTweetMedia","targetLanguage","useTranslateTweetMediaMutation","parseText","text","urlRegex","hashtagRegex","symbolRegex","matches","match","matchIndex","a","b","parts","lastIndex","key","item","e","hashtagUrl","Translate","data","embed","isTranslate","toggle","t","i18n","useTranslation","isTranslating","translatedText","setTranslatedText","useState","handleTranslate","useCallback","parsedText","Fragment","TranslateIcon","cn","TextExpand","isExpanded","onToggleExpand","renderExpand","ChevronUpIcon","ChevronDownIcon","Content","content","onLoad","ref","useRef","parsedContent","useEffect","current","TweetSource","headerActions","footerActions","indicator","children","setIsExpanded","containerClass","tweet","age","useTickAge","twitterTweetUrl","formatAge","TweetOriginal","TweetQuote","hasSource","TweetReply","sourceTweet","TweetRetweet","TweetItem","loading","TweetSkeleton","tweetType","commonProps","TweetTokenButton","token","color","SafeBigNumber","Button","TweetTokenIcon","formatPercent","ChainIcon","Image","Badge","Tweets","setIsPaused","customHeaderActions","customFooterActions","TweetSkeletonList","count","_","index","useTweets","setMedias","setLoading","isPaused","handleMedia","prevMedias","idx","it","newMedias","subTweet","subTweetToken","TweetsWidget","onPauseChange","createMediaTrackRuntime","generation","connected","localeTransform","listeners","transform","channel","listener","bucket","unsubscribed","payload","next","MediaTrackProvider","MediaTrackClientBridge","basic"],"mappings":"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","file":"index.js","sourcesContent":["import { useBoolean } from \"@liberfi.io/hooks\";\nimport { Skeleton } from \"@liberfi.io/ui\";\n\ntype Props = {\n src: string;\n};\n\n// ------------------------------------------------------------\nexport function MediaImage({ src }: Props) {\n const [isLoaded, { setTrue }] = useBoolean(false);\n if (!src) return null;\n\n return (\n <Skeleton isLoaded={isLoaded} className=\"w-full h-auto\">\n <img\n src={src}\n className=\"w-full h-full object-cover aspect-video\"\n onLoad={() => {\n setTrue();\n }}\n />\n </Skeleton>\n );\n}\n","type Props = {\n src: string;\n};\n\n// ------------------------------------------------------------\nexport function MediaVideo({ src }: Props) {\n if (!src) return null;\n\n return (\n <div className=\"w-full h-full overflow-hidden rounded-md mt-2\">\n <iframe\n className=\"w-full h-full aspect-video\"\n src={src}\n allowFullScreen\n />\n </div>\n );\n}\n","import { Link } from \"@liberfi.io/ui\";\nimport { TweetContentMedia } from \"../../../../types\";\nimport { MediaImage } from \"./media-image\";\nimport { MediaVideo } from \"./media-video\";\n\ntype Props = {\n medias: Array<TweetContentMedia>;\n tweetHref: string;\n};\n\nexport function Medias({ medias, tweetHref }: Props) {\n const images = medias.filter((media) => media.type === \"image\");\n const videos = medias.filter((media) => media.type === \"video\");\n\n const renderVideos = () => {\n if (!videos.length) return null;\n return (\n <div className={`grid grid-cols-1 gap-[1px] overflow-hidden rounded-md`}>\n {videos.map((video) => (\n <MediaVideo key={video.url} src={video.url} />\n ))}\n </div>\n );\n };\n\n const renderImages = () => {\n if (!images.length) return null;\n return (\n <div className={`grid grid-cols-1 gap-[1px] overflow-hidden rounded-md`}>\n {images.map((image) => (\n <Link key={image.url} href={tweetHref} target=\"_blank\">\n <MediaImage src={image.url} />\n </Link>\n ))}\n </div>\n );\n };\n\n return (\n <div className=\"flex flex-col gap-2\">\n {renderVideos()}\n {renderImages()}\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { Avatar, Skeleton } from \"@liberfi.io/ui\";\n\ntype Props = {\n url?: string;\n name?: string;\n size?: number;\n};\n\nexport function UserAvatar({ url, name = \"\", size = 36 }: Props) {\n const fallbackName = useMemo(() => (name ? name.slice(0, 2) : \"N/A\"), [name]);\n\n return (\n <Skeleton\n className=\"flex rounded-full flex-shrink-0\"\n style={{ width: size, height: size }}\n isLoaded={!!url}\n >\n <Avatar\n size=\"md\"\n color=\"primary\"\n radius=\"full\"\n showFallback\n name={fallbackName}\n src={url}\n style={{ width: size, height: size }}\n />\n </Skeleton>\n );\n}\n","import React from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetUser } from \"../../../../types\";\nimport { UserAvatar } from \"./user-avatar\";\n\ntype Props = {\n user: TweetUser;\n renderTimestamp?: React.ReactNode;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function UserInfo({ user, renderTimestamp, renderActions }: Props) {\n return (\n <div className=\"flex items-center justify-between gap-1\">\n <div className=\"flex items-center gap-1\">\n <UserAvatar url={user.avatar} name={user.username} />\n <div className=\"flex flex-col gap-0.5\">\n <div className=\"flex flex-row items-baseline gap-1\">\n <span className=\"text-foreground font-semibold truncate leading-none\">\n {user.username}\n </span>\n {renderTimestamp}\n </div>\n <Link\n target=\"_blank\"\n underline=\"hover\"\n className=\"text-default-500 text-sm leading-none\"\n href={twitterUserUrl(user.screenName ?? user.username)}\n >\n @{user.screenName ?? user.username}\n </Link>\n </div>\n </div>\n {renderActions}\n </div>\n );\n}\n","import { createContext } from \"react\";\nimport { IMediaTrackClient } from \"../types\";\n\nexport interface MediaTrackContextValue {\n client: IMediaTrackClient;\n}\n\nexport const MediaTrackContext = createContext<MediaTrackContextValue>(\n {} as MediaTrackContextValue,\n);\n","import { createContext } from \"react\";\nimport type { TweetMedia } from \"../types\";\nimport type { MediaTrackRuntime } from \"../runtime/media-track-runtime\";\n\nexport const MediaTrackRuntimeContext =\n createContext<MediaTrackRuntime<TweetMedia> | null>(null);\n","import { useContext } from \"react\";\nimport { MediaTrackContext } from \"../context\";\n\nexport function useMediaTrackContext() {\n const context = useContext(MediaTrackContext);\n if (!context) {\n throw new Error(\n \"useMediaTrackContext must be used within a MediaTrackProvider\",\n );\n }\n return context;\n}\n","import { useMediaTrackContext } from \"./useMediaTrackContext\";\n\nexport function useMediaTrackClient() {\n const { client } = useMediaTrackContext();\n return client;\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport { GeneratedMemeInfo, TweetMedia } from \"../types\";\nimport { useMediaTrackClient } from \"./useMediaTrackClient\";\n\nexport function useGenerateTweetMediaMemeMutation(\n options: Omit<\n UseMutationOptions<GeneratedMemeInfo, Error, TweetMedia, string[]>,\n \"mutationFn\"\n > = {},\n) {\n const client = useMediaTrackClient();\n return useMutation({\n mutationFn: async (params: TweetMedia) => client.generateMeme(params),\n ...options,\n });\n}\n","import { useContext } from \"react\";\nimport { MediaTrackRuntimeContext } from \"../context/MediaTrackRuntimeContext\";\n\nexport function useMediaTrackRuntime() {\n const runtime = useContext(MediaTrackRuntimeContext);\n if (!runtime) {\n throw new Error(\n \"useMediaTrackRuntime must be used within a MediaTrackProvider\",\n );\n }\n return runtime;\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport { LocaleCode } from \"@liberfi.io/i18n\";\nimport { IMediaTrackClient, TweetMedia } from \"../types\";\nimport { useMediaTrackClient } from \"./useMediaTrackClient\";\n\nexport interface UseTranslateTweetMediaParams {\n media: TweetMedia;\n targetLanguage: LocaleCode;\n options?: {\n sourceLanguage?: LocaleCode;\n sourceTweet?: boolean;\n };\n}\n\nexport async function translateTweetMedia(\n client: IMediaTrackClient,\n { media, targetLanguage, options }: UseTranslateTweetMediaParams,\n) {\n return await client.translate(media, targetLanguage, options);\n}\n\nexport function useTranslateTweetMediaMutation(\n options: Omit<\n UseMutationOptions<string, Error, UseTranslateTweetMediaParams>,\n \"mutationFn\"\n > = {},\n) {\n const client = useMediaTrackClient();\n return useMutation({\n mutationFn: async (params: UseTranslateTweetMediaParams) =>\n translateTweetMedia(client, params),\n ...options,\n });\n}\n","interface MatchItem {\n index: number;\n length: number;\n text: string;\n type: \"url\" | \"hashtag\" | \"symbol\";\n}\n\nexport function parseText(text: string): (string | React.ReactElement)[] {\n const urlRegex = /(https?:\\/\\/[^\\s]+|www\\.[^\\s]+)/gi;\n const hashtagRegex = /#[\\w]+/g;\n const symbolRegex = /\\$[A-Za-z][A-Za-z0-9_]*/g;\n\n const matches: MatchItem[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = urlRegex.exec(text)) !== null) {\n matches.push({\n index: match.index,\n length: match[0].length,\n text: match[0],\n type: \"url\",\n });\n }\n\n while ((match = hashtagRegex.exec(text)) !== null) {\n const matchIndex = match.index;\n const overlaps = matches.some(\n (m) => matchIndex >= m.index && matchIndex < m.index + m.length,\n );\n if (!overlaps) {\n matches.push({\n index: matchIndex,\n length: match[0].length,\n text: match[0],\n type: \"hashtag\",\n });\n }\n }\n\n while ((match = symbolRegex.exec(text)) !== null) {\n const matchIndex = match.index;\n const overlaps = matches.some(\n (m) => matchIndex >= m.index && matchIndex < m.index + m.length,\n );\n if (!overlaps) {\n matches.push({\n index: matchIndex,\n length: match[0].length,\n text: match[0],\n type: \"symbol\",\n });\n }\n }\n\n matches.sort((a, b) => a.index - b.index);\n\n const parts: (string | React.ReactElement)[] = [];\n let lastIndex = 0;\n let key = 0;\n\n matches.forEach((item) => {\n if (item.index > lastIndex) {\n parts.push(text.slice(lastIndex, item.index));\n }\n\n if (item.type === \"url\") {\n const url = item.text.startsWith(\"http\")\n ? item.text\n : `https://${item.text}`;\n parts.push(\n <a\n key={key++}\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline\"\n onClick={(e) => e.stopPropagation()}\n >\n {item.text}\n </a>,\n );\n } else if (item.type === \"hashtag\") {\n const hashtag = item.text.slice(1); // 移除 #\n const hashtagUrl = `https://x.com/hashtag/${hashtag}`;\n parts.push(\n <a\n key={key++}\n href={hashtagUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline\"\n onClick={(e) => e.stopPropagation()}\n >\n {item.text}\n </a>,\n );\n } else if (item.type === \"symbol\") {\n parts.push(\n <span key={key++} className=\"text-primary\">\n {item.text}\n </span>,\n );\n }\n\n lastIndex = item.index + item.length;\n });\n\n if (lastIndex < text.length) {\n parts.push(text.slice(lastIndex));\n }\n\n return parts.length > 0 ? parts : [text];\n}\n","import React, { MouseEvent, useCallback, useState } from \"react\";\nimport { useBoolean } from \"@liberfi.io/hooks\";\nimport { LocaleCode, useTranslation } from \"@liberfi.io/i18n\";\nimport { cn, Skeleton, TranslateIcon } from \"@liberfi.io/ui\";\nimport { useTranslateTweetMediaMutation } from \"../../../../hooks\";\nimport { TweetMedia } from \"../../../../types\";\nimport { parseText } from \"../../../../utils\";\n\ntype Props = {\n data: TweetMedia;\n embed?: boolean;\n text: string;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function Translate({ data, embed, renderActions }: Props) {\n const [isTranslate, { toggle }] = useBoolean(false);\n\n const { t, i18n } = useTranslation();\n\n const { mutateAsync: translateTweetMedia, isPending: isTranslating } =\n useTranslateTweetMediaMutation();\n\n const [translatedText, setTranslatedText] = useState<\n (string | React.ReactElement)[] | null\n >(null);\n\n const handleTranslate = useCallback(\n async (e: MouseEvent<HTMLDivElement>) => {\n e.stopPropagation();\n toggle();\n if (!translatedText) {\n const text = await translateTweetMedia({\n media: data,\n targetLanguage: i18n.language as LocaleCode,\n options: {\n sourceTweet: embed,\n },\n });\n const parsedText = parseText(text);\n setTranslatedText(parsedText);\n }\n },\n [toggle, translateTweetMedia, data, i18n.language, translatedText, embed],\n );\n\n return (\n <>\n <div className=\"flex items-center gap-1 text-xs\">\n <div\n onClick={handleTranslate}\n className=\"flex items-center gap-0.5 cursor-pointer text-primary hover:text-foreground\"\n >\n <TranslateIcon width=\"14\" height=\"14\" />\n {isTranslate\n ? t(\"mediaTrack.tweets.translate.hide\")\n : t(\"mediaTrack.tweets.translate.show\")}\n </div>\n {renderActions}\n </div>\n <div\n className={cn(!isTranslate && \"hidden\")}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n {isTranslate && (\n <div className=\"bg-content2 rounded-md p-2 text-default-900 text-sm leading-5\">\n {translatedText}\n {isTranslating && <Skeleton className=\"w-full h-4 rounded-md\" />}\n </div>\n )}\n </div>\n </>\n );\n}\n","import { useTranslation } from \"@liberfi.io/i18n\";\nimport { ChevronDownIcon, ChevronUpIcon } from \"@liberfi.io/ui\";\n\ntype Props = {\n isExpanded?: boolean;\n onToggleExpand?: (expanded: boolean) => void;\n};\n\nexport function TextExpand({ isExpanded, onToggleExpand }: Props) {\n const { t } = useTranslation();\n const renderExpand = () => {\n if (isExpanded) {\n return (\n <>\n <ChevronUpIcon\n className=\"border border-current\"\n width=\"12\"\n height=\"12\"\n />\n {t(\"mediaTrack.tweets.collapse\")}\n </>\n );\n }\n\n return (\n <>\n <ChevronDownIcon\n className=\"border border-current\"\n width=\"12\"\n height=\"12\"\n />\n {t(\"mediaTrack.tweets.expand\")}\n </>\n );\n };\n\n if (isExpanded === undefined) return null;\n\n return (\n <div className=\"flex items-center gap-1\">\n <div className=\"w-px h-2.5 bg-line-300\" />\n <button\n onClick={(e) => {\n e.stopPropagation();\n onToggleExpand?.(!isExpanded);\n }}\n className=\"flex items-center text-default-500 hover:text-foreground text-xs\"\n >\n {renderExpand()}\n </button>\n </div>\n );\n}\n","import { useEffect, useMemo, useRef } from \"react\";\nimport { parseText } from \"../../../../utils\";\n\ntype Props = {\n content: string;\n isExpanded?: boolean;\n onLoad?: () => void;\n};\n\n// ------------------------------------------------------------\nexport function Content({ content, isExpanded = false, onLoad }: Props) {\n const ref = useRef<HTMLDivElement>(null);\n\n const parsedContent = useMemo(() => parseText(content), [content]);\n\n useEffect(() => {\n const current = ref.current;\n if (!onLoad || !current) return;\n if (current.scrollHeight > current.clientHeight) {\n onLoad?.();\n }\n }, [isExpanded, onLoad]);\n\n return (\n <div\n ref={ref}\n className={[\n \"text-default-900 text-sm leading-5\",\n !isExpanded ? \"line-clamp-3\" : \"\",\n ].join(\" \")}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n {parsedContent}\n </div>\n );\n}\n","import React, { useMemo, useState } from \"react\";\nimport { useTickAge } from \"@liberfi.io/hooks\";\nimport { cn } from \"@liberfi.io/ui\";\nimport { formatAge, twitterTweetUrl } from \"@liberfi.io/utils\";\nimport { Tweet, TweetMedia } from \"../../../types\";\nimport { Content } from \"./content\";\nimport { Medias } from \"./media\";\nimport { Translate, TextExpand } from \"./tools\";\nimport { UserInfo } from \"./user\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n embed?: boolean;\n indicator?: React.ReactNode;\n children?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetSource({\n data,\n headerActions,\n footerActions,\n embed = false,\n indicator,\n children,\n}: Props) {\n const [isExpanded, setIsExpanded] = useState<boolean | undefined>(undefined);\n\n const containerClass = useMemo(() => {\n return embed\n ? \"bg-default-50 rounded-lg p-3 w-full mx-auto\"\n : \"bg-default-100 hover:bg-default-200 rounded-lg p-3 w-full mx-auto\";\n }, [embed]);\n\n const tweet = useMemo(\n () => (embed ? data.sourceTweet! : data.tweet),\n [data, embed],\n );\n\n const age = useTickAge((tweet as Tweet).timestamp);\n\n return (\n <div\n className={cn(\"flex flex-col gap-1.5 cursor-pointer\", containerClass)}\n onClick={() => {\n window.open(twitterTweetUrl(tweet.tweetId), \"_blank\");\n }}\n >\n {/* -------- USER INFO -------- */}\n <UserInfo\n user={tweet.user}\n renderTimestamp={\n embed ? undefined : (\n <div className=\"text-xs text-primary\">{formatAge(age)}</div>\n )\n }\n renderActions={headerActions}\n />\n\n {/* -------- MESSAGE TYPE INDICATOR -------- */}\n {indicator}\n\n {/* -------- CONTENT -------- */}\n {tweet.content.text && (\n <Content\n content={tweet.content.text}\n isExpanded={isExpanded}\n onLoad={() => setIsExpanded(false)}\n />\n )}\n\n {/* -------- TOOLS -------- */}\n {tweet.content.text && (\n <Translate\n data={data}\n embed={embed}\n text={tweet.content.text}\n renderActions={\n <TextExpand\n isExpanded={isExpanded}\n onToggleExpand={setIsExpanded}\n />\n }\n />\n )}\n\n {/* -------- MEDIA -------- */}\n <div\n className={cn(\n (!tweet.content.medias || tweet.content.medias.length === 0) &&\n \"hidden\",\n )}\n >\n {tweet.content.medias && tweet.content.medias.length > 0 && (\n <Medias\n medias={tweet.content.medias}\n tweetHref={twitterTweetUrl(tweet.tweetId)}\n />\n )}\n </div>\n\n {/* -------- CHILDREN -------- */}\n {children}\n\n {/* -------- Custom ACTIONS -------- */}\n {footerActions}\n </div>\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetOriginal({ data, headerActions, footerActions }: Props) {\n return (\n <TweetSource\n data={data}\n headerActions={headerActions}\n footerActions={footerActions}\n />\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetQuote({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n return (\n <TweetSource\n data={data}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetReply({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n const indicator = useMemo(\n () => (\n <div className=\"flex items-center gap-2 text-sm\">\n <span>Replying to</span>\n {hasSource && (\n <Link\n className=\"text-sm\"\n underline=\"hover\"\n target=\"_blank\"\n href={twitterUserUrl(\n sourceTweet.user.screenName ?? sourceTweet.user.username,\n )}\n >\n @{sourceTweet.user.screenName ?? sourceTweet.user.username}\n </Link>\n )}\n </div>\n ),\n [hasSource, sourceTweet],\n );\n\n return (\n <TweetSource\n data={data}\n indicator={indicator}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetRetweet({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n const indicator = useMemo(\n () => (\n <div className=\"flex items-center gap-2 text-sm\">\n <span>Retweeted by</span>\n {hasSource && (\n <Link\n className=\"text-sm\"\n underline=\"hover\"\n target=\"_blank\"\n href={twitterUserUrl(\n sourceTweet.user.screenName ?? sourceTweet.user.username,\n )}\n >\n @{sourceTweet.user.screenName ?? sourceTweet.user.username}\n </Link>\n )}\n </div>\n ),\n [hasSource, sourceTweet],\n );\n\n return (\n <TweetSource\n data={data}\n indicator={indicator}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React from \"react\";\nimport { Skeleton } from \"@liberfi.io/ui\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetOriginal } from \"./tweet-original\";\nimport { TweetQuote } from \"./tweet-quote\";\nimport { TweetReply } from \"./tweet-reply\";\nimport { TweetRetweet } from \"./tweet-retweet\";\n\ntype Props = {\n data?: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n embed?: boolean;\n children?: React.ReactNode;\n loading?: boolean;\n};\n\n// ------------------------------------------------------------\nexport function TweetItem({\n data,\n headerActions,\n footerActions,\n embed = false,\n children,\n loading = false,\n}: Props) {\n if (loading || !data) {\n return <TweetSkeleton embed={embed} />;\n }\n\n const tweetType = data.tweet.type;\n\n // Render appropriate component based on tweet type\n const renderTweetComponent = () => {\n const commonProps = {\n data,\n headerActions,\n footerActions,\n embed,\n children,\n };\n\n switch (tweetType) {\n case \"reply\":\n return <TweetReply {...commonProps} />;\n case \"retweet\":\n return <TweetRetweet {...commonProps} />;\n case \"quote\":\n return <TweetQuote {...commonProps} />;\n default: // \"original\"\n return <TweetOriginal {...commonProps} />;\n }\n };\n\n return <div className=\"w-full\">{renderTweetComponent()}</div>;\n}\n\n// ------------------------------------------------------------\nfunction TweetSkeleton({ embed = false }: { embed?: boolean }) {\n const containerClass = embed\n ? \"bg-default-50 rounded-lg p-3 w-full mx-auto\"\n : \"bg-default-100 rounded-lg p-3 w-full mx-auto\";\n\n return (\n <div className={[\"flex flex-col gap-2\", containerClass].join(\" \")}>\n {/* User Info Skeleton */}\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"w-10 h-10 rounded-full\" />\n <div className=\"flex flex-col gap-1 flex-1\">\n <Skeleton className=\"h-4 w-24\" />\n <Skeleton className=\"h-3 w-16\" />\n </div>\n <Skeleton className=\"h-3 w-12\" />\n </div>\n\n {/* Content Skeleton */}\n <div className=\"flex flex-col gap-2\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-4 w-1/2\" />\n </div>\n\n {/* Media Skeleton */}\n <Skeleton className=\"h-48 w-full rounded-lg\" />\n\n {/* Actions Skeleton */}\n <div className=\"flex justify-between items-center pt-2\">\n <div className=\"flex gap-4\">\n <Skeleton className=\"h-6 w-16\" />\n <Skeleton className=\"h-6 w-16\" />\n <Skeleton className=\"h-6 w-16\" />\n </div>\n <Skeleton className=\"h-6 w-20\" />\n </div>\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { Avatar, Badge, Button, Image } from \"@liberfi.io/ui\";\nimport { formatPercent, SafeBigNumber } from \"@liberfi.io/utils\";\nimport { MediaToken } from \"../../../../types\";\n\ntype Props = {\n token: MediaToken;\n};\n\nexport function TweetTokenButton({ token }: Props) {\n const color = new SafeBigNumber(token.priceChange ?? \"0\").isPositive()\n ? \"primary\"\n : \"danger\";\n\n return (\n <Button\n color={color}\n variant=\"flat\"\n size=\"sm\"\n radius=\"full\"\n startContent={<TweetTokenIcon token={token} />}\n >\n <span>{token.symbol}</span>\n <span>\n {token.priceChange\n ? formatPercent(Number(token.priceChange) / 100)\n : \"--\"}\n </span>\n </Button>\n );\n}\n\nexport function TweetTokenIcon({ token }: Props) {\n const ChainIcon = useMemo(() => {\n return (\n <Image className=\"w-full h-full\" src={token.image} alt={token.chain} />\n );\n }, [token.chain, token.image]);\n\n return (\n <Badge\n className=\"w-2.5 h-2.5 p-0 border\"\n size=\"sm\"\n content={ChainIcon}\n shape=\"circle\"\n placement=\"bottom-right\"\n >\n <Avatar className=\"w-5 h-5\" radius=\"full\" src={token.image} />\n </Badge>\n );\n}\n","import { useCallback } from \"react\";\nimport { TweetMedia } from \"../../types\";\nimport { TweetTokenButton } from \"./tweet/tools/tweet-token-button\";\n// import { TweetTradeButton } from \"./tweet/tools/tweet-trade-button\";\nimport { TweetItem } from \"./tweet/tweet-item\";\n\ntype TweetsProps = {\n data: Array<TweetMedia>;\n loading: boolean;\n setIsPaused: (paused: boolean) => void;\n customHeaderActions?: (item: TweetMedia) => React.ReactNode;\n customFooterActions?: (item: TweetMedia) => React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function Tweets({\n data,\n loading,\n setIsPaused,\n customHeaderActions,\n customFooterActions,\n}: TweetsProps) {\n const footerActions = useCallback(\n (item: TweetMedia) => (\n <div className=\"flex gap-2.5 justify-between\">\n {item.token && <TweetTokenButton token={item.token} />}\n {customFooterActions?.(item)}\n {/* {item.token && <TweetTradeButton token={item.token} />} */}\n </div>\n ),\n [customFooterActions],\n );\n\n return (\n <div\n className=\"flex flex-col gap-2.5\"\n onMouseEnter={() => setIsPaused(true)}\n onMouseLeave={() => setIsPaused(false)}\n >\n {data.map((item: TweetMedia) => (\n <TweetItem\n key={item.id}\n data={item}\n headerActions={customHeaderActions?.(item)}\n footerActions={footerActions(item)}\n loading={loading}\n />\n ))}\n </div>\n );\n}\n","import { Skeleton } from \"@liberfi.io/ui\";\n\n// ------------------------------------------------------------\nexport function TweetSkeleton() {\n return (\n <div className=\"flex flex-col gap-2 bg-default-100 rounded-lg p-3 w-full mx-auto\">\n {/* User Info Skeleton */}\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"w-10 h-10 rounded-full\" />\n <div className=\"flex flex-col gap-1 flex-1\">\n <Skeleton className=\"h-4 w-40 rounded-md\" />\n <Skeleton className=\"h-3 w-32 rounded-md\" />\n </div>\n </div>\n\n {/* Content Skeleton */}\n <div className=\"flex flex-col gap-2\">\n <Skeleton className=\"h-4 w-full rounded-md\" />\n <Skeleton className=\"h-4 w-3/4 rounded-md\" />\n <Skeleton className=\"h-4 w-1/2 rounded-md\" />\n </div>\n\n {/* Media Skeleton */}\n <Skeleton className=\"h-48 w-full rounded-lg\" />\n </div>\n );\n}\n\nexport function TweetSkeletonList({ count = 3 }: { count: number }) {\n return (\n <div className=\"flex flex-col gap-2\">\n {Array.from({ length: count }).map((_, index) => (\n <TweetSkeleton key={index} />\n ))}\n </div>\n );\n}\n","import { useCallback, useEffect, useState } from \"react\";\nimport { useMediaTrackRuntime } from \"../../hooks/useMediaTrackRuntime\";\nimport { TweetMedia } from \"../../types\";\n\nexport const useTweets = () => {\n const [medias, setMedias] = useState<Array<TweetMedia>>([]);\n const [loading, setLoading] = useState(true);\n const [isPaused, setIsPaused] = useState(false);\n\n const runtime = useMediaTrackRuntime();\n\n const handleMedia = useCallback(\n (media: TweetMedia) => {\n setMedias((prevMedias) => {\n const idx = prevMedias.findIndex((it) => it.id === media.id);\n let newMedias: Array<TweetMedia>;\n\n if (idx >= 0) {\n newMedias = prevMedias.map((item, index) =>\n index === idx ? media : item,\n );\n } else {\n if (isPaused) {\n return prevMedias;\n }\n newMedias = [media, ...prevMedias];\n }\n\n return newMedias.slice(0, 30);\n });\n setLoading(false);\n },\n [isPaused],\n );\n\n useEffect(() => {\n const subTweet = runtime.subscribe(\"x-monitor-basic\", handleMedia);\n const subTweetToken = runtime.subscribe(\"x-monitor-token\", handleMedia);\n return () => {\n subTweet.unsubscribe();\n subTweetToken.unsubscribe();\n };\n }, [runtime, handleMedia]);\n\n return { medias, loading, isPaused, setIsPaused };\n};\n","import { useEffect } from \"react\";\nimport { TweetMedia } from \"../../types\";\nimport { TweetSkeletonList } from \"./tweet/tweet-skeleton\";\nimport { useTweets } from \"./tweets.script\";\nimport { Tweets } from \"./tweets.ui\";\n\n// ------------------------------------------------------------\nexport type TweetsWidgetProps = {\n onPauseChange?: (paused: boolean) => void;\n customHeaderActions?: (item: TweetMedia) => React.ReactNode;\n customFooterActions?: (item: TweetMedia) => React.ReactNode;\n};\n\nexport function TweetsWidget({\n onPauseChange,\n customHeaderActions,\n customFooterActions,\n}: TweetsWidgetProps) {\n const { medias, loading, isPaused, setIsPaused } = useTweets();\n\n useEffect(() => {\n onPauseChange?.(isPaused);\n }, [isPaused, onPauseChange]);\n\n if (loading) {\n return <TweetSkeletonList count={3} />;\n }\n\n return (\n <Tweets\n data={medias}\n loading={loading}\n setIsPaused={setIsPaused}\n customHeaderActions={customHeaderActions}\n customFooterActions={customFooterActions}\n />\n );\n}\n","export type MediaTrackUnsubscribe = () => void;\n\nexport interface MediaTrackSubscription {\n unsubscribe: MediaTrackUnsubscribe;\n}\n\nexport interface MediaTrackRuntime<T = unknown> {\n readonly generation: number;\n connect(): void;\n disconnect(): void;\n setLocaleTransform(transform: ((payload: T) => T) | null): void;\n subscribe(channel: string, listener: (payload: T) => void): MediaTrackSubscription;\n publish(channel: string, payload: T): void;\n}\n\nexport function createMediaTrackRuntime<T = unknown>(): MediaTrackRuntime<T> {\n let generation = 0;\n let connected = false;\n let localeTransform: ((payload: T) => T) | null = null;\n const listeners = new Map<string, Set<(payload: T) => void>>();\n\n return {\n get generation() {\n return generation;\n },\n connect() {\n generation += 1;\n connected = true;\n },\n disconnect() {\n connected = false;\n },\n setLocaleTransform(transform) {\n localeTransform = transform;\n },\n subscribe(channel, listener) {\n let bucket = listeners.get(channel);\n if (!bucket) {\n bucket = new Set();\n listeners.set(channel, bucket);\n }\n bucket.add(listener);\n let unsubscribed = false;\n return {\n unsubscribe() {\n if (unsubscribed) return;\n unsubscribed = true;\n const current = listeners.get(channel);\n current?.delete(listener);\n if (current && current.size === 0) {\n listeners.delete(channel);\n }\n },\n };\n },\n publish(channel, payload) {\n if (!connected) return;\n const next = localeTransform ? localeTransform(payload) : payload;\n listeners.get(channel)?.forEach((listener) => listener(next));\n },\n };\n}\n","import { PropsWithChildren, useContext, useEffect, useMemo } from \"react\";\nimport { MediaTrackContext } from \"../context\";\nimport { MediaTrackRuntimeContext } from \"../context/MediaTrackRuntimeContext\";\nimport { createMediaTrackRuntime } from \"../runtime/media-track-runtime\";\nimport type { IMediaTrackClient, TweetMedia } from \"../types\";\n\nexport type MediaTrackProviderProps = PropsWithChildren<{\n client: IMediaTrackClient;\n}>;\n\nexport function MediaTrackProvider({\n client,\n children,\n}: MediaTrackProviderProps) {\n const runtime = useMemo(() => createMediaTrackRuntime<TweetMedia>(), []);\n\n return (\n <MediaTrackContext.Provider value={{ client }}>\n <MediaTrackRuntimeContext.Provider value={runtime}>\n <MediaTrackClientBridge client={client} />\n {children}\n </MediaTrackRuntimeContext.Provider>\n </MediaTrackContext.Provider>\n );\n}\n\nfunction MediaTrackClientBridge({ client }: { client: IMediaTrackClient }) {\n const runtime = useContext(MediaTrackRuntimeContext);\n useEffect(() => {\n if (!runtime) return;\n runtime.connect();\n const basic = client.subscribeTweetMedia({\n callback: (media) => runtime.publish(\"x-monitor-basic\", media),\n });\n const token = client.subscribeTweetMediaToken({\n callback: (media) => runtime.publish(\"x-monitor-token\", media),\n });\n return () => {\n basic.unsubscribe();\n token.unsubscribe();\n runtime.disconnect();\n };\n }, [client, runtime]);\n return null;\n}\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {useBoolean,useTickAge}from'@liberfi.io/hooks';import {Skeleton,Avatar,Link,TranslateIcon,cn,ChevronUpIcon,ChevronDownIcon,Button,Image,Badge}from'@liberfi.io/ui';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {twitterUserUrl,formatAge,twitterTweetUrl,SafeBigNumber,formatPercent}from'@liberfi.io/utils';import {createContext,useMemo,useContext,useState,useCallback,useEffect,useRef}from'react';import {useTranslation}from'@liberfi.io/i18n';import {useMutation}from'@tanstack/react-query';function F({src:e}){let[t,{setTrue:r}]=useBoolean(false);return e?jsx(Skeleton,{isLoaded:t,className:"w-full h-auto",children:jsx("img",{src:e,className:"w-full h-full object-cover aspect-video",onLoad:()=>{r();}})}):null}function V({src:e}){return e?jsx("div",{className:"w-full h-full overflow-hidden rounded-md mt-2",children:jsx("iframe",{className:"w-full h-full aspect-video",src:e,allowFullScreen:true})}):null}function W({medias:e,tweetHref:t}){let r=e.filter(s=>s.type==="image"),a=e.filter(s=>s.type==="video"),n=()=>a.length?jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:a.map(s=>jsx(V,{src:s.url},s.url))}):null,i=()=>r.length?jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:r.map(s=>jsx(Link,{href:t,target:"_blank",children:jsx(F,{src:s.url})},s.url))}):null;return jsxs("div",{className:"flex flex-col gap-2",children:[n(),i()]})}function D({url:e,name:t="",size:r=36}){let a=useMemo(()=>t?t.slice(0,2):"N/A",[t]);return jsx(Skeleton,{className:"flex rounded-full flex-shrink-0",style:{width:r,height:r},isLoaded:!!e,children:jsx(Avatar,{size:"md",color:"primary",radius:"full",showFallback:true,name:a,src:e,style:{width:r,height:r}})})}function $({user:e,renderTimestamp:t,renderActions:r}){return jsxs("div",{className:"flex items-center justify-between gap-1",children:[jsxs("div",{className:"flex items-center gap-1",children:[jsx(D,{url:e.avatar,name:e.username}),jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxs("div",{className:"flex flex-row items-baseline gap-1",children:[jsx("span",{className:"text-foreground font-semibold truncate leading-none",children:e.username}),t]}),jsxs(Link,{target:"_blank",underline:"hover",className:"text-default-500 text-sm leading-none",href:twitterUserUrl(e.screenName??e.username),children:["@",e.screenName??e.username]})]})]}),r]})}var b=createContext({});function Q(){let e=useContext(b);if(!e)throw new Error("useMediaTrackContext must be used within a MediaTrackProvider");return e}function h(){let{client:e}=Q();return e}function ro(e={}){let t=h();return useMutation({mutationFn:async r=>t.generateMeme(r),...e})}async function Ce(e,{media:t,targetLanguage:r,options:a}){return await e.translate(t,r,a)}function Z(e={}){let t=h();return useMutation({mutationFn:async r=>Ce(t,r),...e})}function y(e){let t=/(https?:\/\/[^\s]+|www\.[^\s]+)/gi,r=/#[\w]+/g,a=/\$[A-Za-z][A-Za-z0-9_]*/g,n=[],i;for(;(i=t.exec(e))!==null;)n.push({index:i.index,length:i[0].length,text:i[0],type:"url"});for(;(i=r.exec(e))!==null;){let o=i.index;n.some(d=>o>=d.index&&o<d.index+d.length)||n.push({index:o,length:i[0].length,text:i[0],type:"hashtag"});}for(;(i=a.exec(e))!==null;){let o=i.index;n.some(d=>o>=d.index&&o<d.index+d.length)||n.push({index:o,length:i[0].length,text:i[0],type:"symbol"});}n.sort((o,p)=>o.index-p.index);let s=[],m=0,l=0;return n.forEach(o=>{if(o.index>m&&s.push(e.slice(m,o.index)),o.type==="url"){let p=o.text.startsWith("http")?o.text:`https://${o.text}`;s.push(jsx("a",{href:p,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:d=>d.stopPropagation(),children:o.text},l++));}else if(o.type==="hashtag"){let d=`https://x.com/hashtag/${o.text.slice(1)}`;s.push(jsx("a",{href:d,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:x=>x.stopPropagation(),children:o.text},l++));}else o.type==="symbol"&&s.push(jsx("span",{className:"text-primary",children:o.text},l++));m=o.index+o.length;}),m<e.length&&s.push(e.slice(m)),s.length>0?s:[e]}function q({data:e,embed:t,renderActions:r}){let[a,{toggle:n}]=useBoolean(false),{t:i,i18n:s}=useTranslation(),{mutateAsync:m,isPending:l}=Z(),[o,p]=useState(null),d=useCallback(async x=>{if(x.stopPropagation(),n(),!o){let A=await m({media:e,targetLanguage:s.language,options:{sourceTweet:t}}),ue=y(A);p(ue);}},[n,m,e,s.language,o]);return jsxs(Fragment,{children:[jsxs("div",{className:"flex items-center gap-1 text-xs",children:[jsxs("div",{onClick:d,className:"flex items-center gap-0.5 cursor-pointer text-primary hover:text-foreground",children:[jsx(TranslateIcon,{width:"14",height:"14"}),i(a?"mediaTrack.tweets.translate.hide":"mediaTrack.tweets.translate.show")]}),r]}),jsx("div",{className:cn(!a&&"hidden"),onClick:x=>{x.stopPropagation();},children:a&&jsxs("div",{className:"bg-content2 rounded-md p-2 text-default-900 text-sm leading-5",children:[o,l&&jsx(Skeleton,{className:"w-full h-4 rounded-md"})]})})]})}function K({isExpanded:e,onToggleExpand:t}){let{t:r}=useTranslation(),a=()=>e?jsxs(Fragment,{children:[jsx(ChevronUpIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",r("mediaTrack.tweets.collapse")]}):jsxs(Fragment,{children:[jsx(ChevronDownIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",r("mediaTrack.tweets.expand")]});return e===void 0?null:jsxs("div",{className:"flex items-center gap-1",children:[jsx("div",{className:"w-px h-2.5 bg-line-300"}),jsx("button",{onClick:n=>{n.stopPropagation(),t?.(!e);},className:"flex items-center text-default-500 hover:text-foreground text-xs",children:a()})]})}function X({content:e,isExpanded:t=false,onLoad:r}){let a=useRef(null),n=useMemo(()=>y(e),[e]);return useEffect(()=>{let i=a.current;!r||!i||i.scrollHeight>i.clientHeight&&r?.();},[t]),jsx("div",{ref:a,className:["text-default-900 text-sm leading-5",t?"":"line-clamp-3"].join(" "),onClick:i=>{i.stopPropagation();},children:n})}function u({data:e,headerActions:t,footerActions:r,embed:a=false,indicator:n,children:i}){let[s,m]=useState(void 0),l=useMemo(()=>a?"bg-default-50 rounded-lg p-3 w-full mx-auto":"bg-default-100 hover:bg-default-200 rounded-lg p-3 w-full mx-auto",[a]),o=useMemo(()=>a?e.sourceTweet:e.tweet,[e,a]),p=useTickAge(o.timestamp);return jsxs("div",{className:cn("flex flex-col gap-1.5 cursor-pointer",l),onClick:()=>{window.open(twitterTweetUrl(o.tweetId),"_blank");},children:[jsx($,{user:o.user,renderTimestamp:a?void 0:jsx("div",{className:"text-xs text-primary",children:formatAge(p)}),renderActions:t}),n,o.content.text&&jsx(X,{content:o.content.text,isExpanded:s,onLoad:()=>m(false)}),o.content.text&&jsx(q,{data:e,embed:a,text:o.content.text,renderActions:jsx(K,{isExpanded:s,onToggleExpand:m})}),jsx("div",{className:cn((!o.content.medias||o.content.medias.length===0)&&"hidden"),children:o.content.medias&&o.content.medias.length>0&&jsx(W,{medias:o.content.medias,tweetHref:twitterTweetUrl(o.tweetId)})}),i,r]})}function te({data:e,headerActions:t,footerActions:r}){return jsx(u,{data:e,headerActions:t,footerActions:r})}function re({data:e,headerActions:t,footerActions:r}){let n=!!e.sourceTweet;return jsx(u,{data:e,headerActions:t,footerActions:r,children:n?jsx(u,{data:e,embed:true}):null})}function ne({data:e,headerActions:t,footerActions:r}){let a=e.sourceTweet,n=!!a,i=useMemo(()=>jsxs("div",{className:"flex items-center gap-2 text-sm",children:[jsx("span",{children:"Replying to"}),n&&jsxs(Link,{className:"text-sm",underline:"hover",target:"_blank",href:twitterUserUrl(a.user.screenName??a.user.username),children:["@",a.user.screenName??a.user.username]})]}),[n,a]);return jsx(u,{data:e,indicator:i,headerActions:t,footerActions:r,children:n?jsx(u,{data:e,embed:true}):null})}function ie({data:e,headerActions:t,footerActions:r}){let a=e.sourceTweet,n=!!a,i=useMemo(()=>jsxs("div",{className:"flex items-center gap-2 text-sm",children:[jsx("span",{children:"Retweeted by"}),n&&jsxs(Link,{className:"text-sm",underline:"hover",target:"_blank",href:twitterUserUrl(a.user.screenName??a.user.username),children:["@",a.user.screenName??a.user.username]})]}),[n,a]);return jsx(u,{data:e,indicator:i,headerActions:t,footerActions:r,children:n?jsx(u,{data:e,embed:true}):null})}function le({data:e,headerActions:t,footerActions:r,embed:a=false,children:n,loading:i=false}){if(i||!e)return jsx(tt,{embed:a});let s=e.tweet.type;return jsx("div",{className:"w-full",children:(()=>{let l={data:e,headerActions:t,footerActions:r,embed:a,children:n};switch(s){case "reply":return jsx(ne,{...l});case "retweet":return jsx(ie,{...l});case "quote":return jsx(re,{...l});default:return jsx(te,{...l})}})()})}function tt({embed:e=false}){return jsxs("div",{className:["flex flex-col gap-2",e?"bg-default-50 rounded-lg p-3 w-full mx-auto":"bg-default-100 rounded-lg p-3 w-full mx-auto"].join(" "),children:[jsxs("div",{className:"flex items-center gap-3",children:[jsx(Skeleton,{className:"w-10 h-10 rounded-full"}),jsxs("div",{className:"flex flex-col gap-1 flex-1",children:[jsx(Skeleton,{className:"h-4 w-24"}),jsx(Skeleton,{className:"h-3 w-16"})]}),jsx(Skeleton,{className:"h-3 w-12"})]}),jsxs("div",{className:"flex flex-col gap-2",children:[jsx(Skeleton,{className:"h-4 w-full"}),jsx(Skeleton,{className:"h-4 w-3/4"}),jsx(Skeleton,{className:"h-4 w-1/2"})]}),jsx(Skeleton,{className:"h-48 w-full rounded-lg"}),jsxs("div",{className:"flex justify-between items-center pt-2",children:[jsxs("div",{className:"flex gap-4",children:[jsx(Skeleton,{className:"h-6 w-16"}),jsx(Skeleton,{className:"h-6 w-16"}),jsx(Skeleton,{className:"h-6 w-16"})]}),jsx(Skeleton,{className:"h-6 w-20"})]})]})}function ce({token:e}){let t=new SafeBigNumber(e.priceChange??"0").isPositive()?"primary":"danger";return jsxs(Button,{color:t,variant:"flat",size:"sm",radius:"full",startContent:jsx(ct,{token:e}),children:[jsx("span",{children:e.symbol}),jsx("span",{children:e.priceChange?formatPercent(Number(e.priceChange)/100):"--"})]})}function ct({token:e}){let t=useMemo(()=>jsx(Image,{className:"w-full h-full",src:e.image,alt:e.chain}),[e.chain]);return jsx(Badge,{className:"w-2.5 h-2.5 p-0 border",size:"sm",content:t,shape:"circle",placement:"bottom-right",children:jsx(Avatar,{className:"w-5 h-5",radius:"full",src:e.image})})}function de({data:e,loading:t,setIsPaused:r,customHeaderActions:a,customFooterActions:n}){let i=useCallback(s=>jsxs("div",{className:"flex gap-2.5 justify-between",children:[s.token&&jsx(ce,{token:s.token}),n?.(s)]}),[n]);return jsx("div",{className:"flex flex-col gap-2.5",onMouseEnter:()=>r(true),onMouseLeave:()=>r(false),children:e.map(s=>jsx(le,{data:s,headerActions:a?.(s),footerActions:i(s),loading:t},s.id))})}function ft(){return jsxs("div",{className:"flex flex-col gap-2 bg-default-100 rounded-lg p-3 w-full mx-auto",children:[jsxs("div",{className:"flex items-center gap-3",children:[jsx(Skeleton,{className:"w-10 h-10 rounded-full"}),jsxs("div",{className:"flex flex-col gap-1 flex-1",children:[jsx(Skeleton,{className:"h-4 w-40 rounded-md"}),jsx(Skeleton,{className:"h-3 w-32 rounded-md"})]})]}),jsxs("div",{className:"flex flex-col gap-2",children:[jsx(Skeleton,{className:"h-4 w-full rounded-md"}),jsx(Skeleton,{className:"h-4 w-3/4 rounded-md"}),jsx(Skeleton,{className:"h-4 w-1/2 rounded-md"})]}),jsx(Skeleton,{className:"h-48 w-full rounded-lg"})]})}function me({count:e=3}){return jsx("div",{className:"flex flex-col gap-2",children:Array.from({length:e}).map((t,r)=>jsx(ft,{},r))})}var pe=()=>{let[e,t]=useState([]),[r,a]=useState(true),[n,i]=useState(false),s=h(),m=useCallback(l=>{t(o=>{let p=o.findIndex(x=>x.id===l.id),d;if(p>=0)d=o.map((x,A)=>A===p?l:x);else {if(n)return o;d=[l,...o];}return d.slice(0,30)}),a(false);},[n]);return useEffect(()=>{let l=s.subscribeTweetMedia({callback:m}),o=s.subscribeTweetMediaToken({callback:m});return ()=>{l.unsubscribe(),o.unsubscribe();}},[s,m]),{medias:e,loading:r,isPaused:n,setIsPaused:i}};function oa({onPauseChange:e,customHeaderActions:t,customFooterActions:r}){let{medias:a,loading:n,isPaused:i,setIsPaused:s}=pe();return useEffect(()=>{e?.(i);},[i,e]),n?jsx(me,{count:3}):jsx(de,{data:a,loading:n,setIsPaused:s,customHeaderActions:t,customFooterActions:r})}function ua({client:e,children:t}){return jsx(b.Provider,{value:{client:e},children:t})}
|
|
2
|
-
export{
|
|
1
|
+
import {useBoolean,useTickAge}from'@liberfi.io/hooks';import {Skeleton,Avatar,Link,TranslateIcon,cn,ChevronUpIcon,ChevronDownIcon,Button,Image,Badge}from'@liberfi.io/ui';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {twitterUserUrl,formatAge,twitterTweetUrl,SafeBigNumber,formatPercent}from'@liberfi.io/utils';import {createContext,useMemo,useContext,useState,useCallback,useEffect,useRef}from'react';import {useTranslation}from'@liberfi.io/i18n';import {useMutation}from'@tanstack/react-query';function S({src:e}){let[t,{setTrue:r}]=useBoolean(false);return e?jsx(Skeleton,{isLoaded:t,className:"w-full h-auto",children:jsx("img",{src:e,className:"w-full h-full object-cover aspect-video",onLoad:()=>{r();}})}):null}function E({src:e}){return e?jsx("div",{className:"w-full h-full overflow-hidden rounded-md mt-2",children:jsx("iframe",{className:"w-full h-full aspect-video",src:e,allowFullScreen:true})}):null}function L({medias:e,tweetHref:t}){let r=e.filter(i=>i.type==="image"),o=e.filter(i=>i.type==="video"),a=()=>o.length?jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:o.map(i=>jsx(E,{src:i.url},i.url))}):null,s=()=>r.length?jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:r.map(i=>jsx(Link,{href:t,target:"_blank",children:jsx(S,{src:i.url})},i.url))}):null;return jsxs("div",{className:"flex flex-col gap-2",children:[a(),s()]})}function U({url:e,name:t="",size:r=36}){let o=useMemo(()=>t?t.slice(0,2):"N/A",[t]);return jsx(Skeleton,{className:"flex rounded-full flex-shrink-0",style:{width:r,height:r},isLoaded:!!e,children:jsx(Avatar,{size:"md",color:"primary",radius:"full",showFallback:true,name:o,src:e,style:{width:r,height:r}})})}function B({user:e,renderTimestamp:t,renderActions:r}){return jsxs("div",{className:"flex items-center justify-between gap-1",children:[jsxs("div",{className:"flex items-center gap-1",children:[jsx(U,{url:e.avatar,name:e.username}),jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxs("div",{className:"flex flex-row items-baseline gap-1",children:[jsx("span",{className:"text-foreground font-semibold truncate leading-none",children:e.username}),t]}),jsxs(Link,{target:"_blank",underline:"hover",className:"text-default-500 text-sm leading-none",href:twitterUserUrl(e.screenName??e.username),children:["@",e.screenName??e.username]})]})]}),r]})}var N=createContext({});var h=createContext(null);function O(){let e=useContext(N);if(!e)throw new Error("useMediaTrackContext must be used within a MediaTrackProvider");return e}function y(){let{client:e}=O();return e}function Ue(e={}){let t=y();return useMutation({mutationFn:async r=>t.generateMeme(r),...e})}function H(){let e=useContext(h);if(!e)throw new Error("useMediaTrackRuntime must be used within a MediaTrackProvider");return e}async function se(e,{media:t,targetLanguage:r,options:o}){return await e.translate(t,r,o)}function _(e={}){let t=y();return useMutation({mutationFn:async r=>se(t,r),...e})}function R(e){let t=/(https?:\/\/[^\s]+|www\.[^\s]+)/gi,r=/#[\w]+/g,o=/\$[A-Za-z][A-Za-z0-9_]*/g,a=[],s;for(;(s=t.exec(e))!==null;)a.push({index:s.index,length:s[0].length,text:s[0],type:"url"});for(;(s=r.exec(e))!==null;){let n=s.index;a.some(m=>n>=m.index&&n<m.index+m.length)||a.push({index:n,length:s[0].length,text:s[0],type:"hashtag"});}for(;(s=o.exec(e))!==null;){let n=s.index;a.some(m=>n>=m.index&&n<m.index+m.length)||a.push({index:n,length:s[0].length,text:s[0],type:"symbol"});}a.sort((n,u)=>n.index-u.index);let i=[],d=0,c=0;return a.forEach(n=>{if(n.index>d&&i.push(e.slice(d,n.index)),n.type==="url"){let u=n.text.startsWith("http")?n.text:`https://${n.text}`;i.push(jsx("a",{href:u,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:m=>m.stopPropagation(),children:n.text},c++));}else if(n.type==="hashtag"){let m=`https://x.com/hashtag/${n.text.slice(1)}`;i.push(jsx("a",{href:m,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:T=>T.stopPropagation(),children:n.text},c++));}else n.type==="symbol"&&i.push(jsx("span",{className:"text-primary",children:n.text},c++));d=n.index+n.length;}),d<e.length&&i.push(e.slice(d)),i.length>0?i:[e]}function W({data:e,embed:t,renderActions:r}){let[o,{toggle:a}]=useBoolean(false),{t:s,i18n:i}=useTranslation(),{mutateAsync:d,isPending:c}=_(),[n,u]=useState(null),m=useCallback(async T=>{if(T.stopPropagation(),a(),!n){let I=await d({media:e,targetLanguage:i.language,options:{sourceTweet:t}}),Me=R(I);u(Me);}},[a,d,e,i.language,n,t]);return jsxs(Fragment,{children:[jsxs("div",{className:"flex items-center gap-1 text-xs",children:[jsxs("div",{onClick:m,className:"flex items-center gap-0.5 cursor-pointer text-primary hover:text-foreground",children:[jsx(TranslateIcon,{width:"14",height:"14"}),s(o?"mediaTrack.tweets.translate.hide":"mediaTrack.tweets.translate.show")]}),r]}),jsx("div",{className:cn(!o&&"hidden"),onClick:T=>{T.stopPropagation();},children:o&&jsxs("div",{className:"bg-content2 rounded-md p-2 text-default-900 text-sm leading-5",children:[n,c&&jsx(Skeleton,{className:"w-full h-4 rounded-md"})]})})]})}function z({isExpanded:e,onToggleExpand:t}){let{t:r}=useTranslation(),o=()=>e?jsxs(Fragment,{children:[jsx(ChevronUpIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",r("mediaTrack.tweets.collapse")]}):jsxs(Fragment,{children:[jsx(ChevronDownIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",r("mediaTrack.tweets.expand")]});return e===void 0?null:jsxs("div",{className:"flex items-center gap-1",children:[jsx("div",{className:"w-px h-2.5 bg-line-300"}),jsx("button",{onClick:a=>{a.stopPropagation(),t?.(!e);},className:"flex items-center text-default-500 hover:text-foreground text-xs",children:o()})]})}function de({content:e,isExpanded:t=false,onLoad:r}){let o=useRef(null),a=useMemo(()=>R(e),[e]);return useEffect(()=>{let s=o.current;!r||!s||s.scrollHeight>s.clientHeight&&r?.();},[t,r]),jsx("div",{ref:o,className:["text-default-900 text-sm leading-5",t?"":"line-clamp-3"].join(" "),onClick:s=>{s.stopPropagation();},children:a})}function p({data:e,headerActions:t,footerActions:r,embed:o=false,indicator:a,children:s}){let[i,d]=useState(void 0),c=useMemo(()=>o?"bg-default-50 rounded-lg p-3 w-full mx-auto":"bg-default-100 hover:bg-default-200 rounded-lg p-3 w-full mx-auto",[o]),n=useMemo(()=>o?e.sourceTweet:e.tweet,[e,o]),u=useTickAge(n.timestamp);return jsxs("div",{className:cn("flex flex-col gap-1.5 cursor-pointer",c),onClick:()=>{window.open(twitterTweetUrl(n.tweetId),"_blank");},children:[jsx(B,{user:n.user,renderTimestamp:o?void 0:jsx("div",{className:"text-xs text-primary",children:formatAge(u)}),renderActions:t}),a,n.content.text&&jsx(de,{content:n.content.text,isExpanded:i,onLoad:()=>d(false)}),n.content.text&&jsx(W,{data:e,embed:o,text:n.content.text,renderActions:jsx(z,{isExpanded:i,onToggleExpand:d})}),jsx("div",{className:cn((!n.content.medias||n.content.medias.length===0)&&"hidden"),children:n.content.medias&&n.content.medias.length>0&&jsx(L,{medias:n.content.medias,tweetHref:twitterTweetUrl(n.tweetId)})}),s,r]})}function D({data:e,headerActions:t,footerActions:r}){return jsx(p,{data:e,headerActions:t,footerActions:r})}function Q({data:e,headerActions:t,footerActions:r}){let a=!!e.sourceTweet;return jsx(p,{data:e,headerActions:t,footerActions:r,children:a?jsx(p,{data:e,embed:true}):null})}function Z({data:e,headerActions:t,footerActions:r}){let o=e.sourceTweet,a=!!o,s=useMemo(()=>jsxs("div",{className:"flex items-center gap-2 text-sm",children:[jsx("span",{children:"Replying to"}),a&&jsxs(Link,{className:"text-sm",underline:"hover",target:"_blank",href:twitterUserUrl(o.user.screenName??o.user.username),children:["@",o.user.screenName??o.user.username]})]}),[a,o]);return jsx(p,{data:e,indicator:s,headerActions:t,footerActions:r,children:a?jsx(p,{data:e,embed:true}):null})}function J({data:e,headerActions:t,footerActions:r}){let o=e.sourceTweet,a=!!o,s=useMemo(()=>jsxs("div",{className:"flex items-center gap-2 text-sm",children:[jsx("span",{children:"Retweeted by"}),a&&jsxs(Link,{className:"text-sm",underline:"hover",target:"_blank",href:twitterUserUrl(o.user.screenName??o.user.username),children:["@",o.user.screenName??o.user.username]})]}),[a,o]);return jsx(p,{data:e,indicator:s,headerActions:t,footerActions:r,children:a?jsx(p,{data:e,embed:true}):null})}function K({data:e,headerActions:t,footerActions:r,embed:o=false,children:a,loading:s=false}){if(s||!e)return jsx(dt,{embed:o});let i=e.tweet.type;return jsx("div",{className:"w-full",children:(()=>{let c={data:e,headerActions:t,footerActions:r,embed:o,children:a};switch(i){case "reply":return jsx(Z,{...c});case "retweet":return jsx(J,{...c});case "quote":return jsx(Q,{...c});default:return jsx(D,{...c})}})()})}function dt({embed:e=false}){return jsxs("div",{className:["flex flex-col gap-2",e?"bg-default-50 rounded-lg p-3 w-full mx-auto":"bg-default-100 rounded-lg p-3 w-full mx-auto"].join(" "),children:[jsxs("div",{className:"flex items-center gap-3",children:[jsx(Skeleton,{className:"w-10 h-10 rounded-full"}),jsxs("div",{className:"flex flex-col gap-1 flex-1",children:[jsx(Skeleton,{className:"h-4 w-24"}),jsx(Skeleton,{className:"h-3 w-16"})]}),jsx(Skeleton,{className:"h-3 w-12"})]}),jsxs("div",{className:"flex flex-col gap-2",children:[jsx(Skeleton,{className:"h-4 w-full"}),jsx(Skeleton,{className:"h-4 w-3/4"}),jsx(Skeleton,{className:"h-4 w-1/2"})]}),jsx(Skeleton,{className:"h-48 w-full rounded-lg"}),jsxs("div",{className:"flex justify-between items-center pt-2",children:[jsxs("div",{className:"flex gap-4",children:[jsx(Skeleton,{className:"h-6 w-16"}),jsx(Skeleton,{className:"h-6 w-16"}),jsx(Skeleton,{className:"h-6 w-16"})]}),jsx(Skeleton,{className:"h-6 w-20"})]})]})}function xe({token:e}){let t=new SafeBigNumber(e.priceChange??"0").isPositive()?"primary":"danger";return jsxs(Button,{color:t,variant:"flat",size:"sm",radius:"full",startContent:jsx(wt,{token:e}),children:[jsx("span",{children:e.symbol}),jsx("span",{children:e.priceChange?formatPercent(Number(e.priceChange)/100):"--"})]})}function wt({token:e}){let t=useMemo(()=>jsx(Image,{className:"w-full h-full",src:e.image,alt:e.chain}),[e.chain,e.image]);return jsx(Badge,{className:"w-2.5 h-2.5 p-0 border",size:"sm",content:t,shape:"circle",placement:"bottom-right",children:jsx(Avatar,{className:"w-5 h-5",radius:"full",src:e.image})})}function Y({data:e,loading:t,setIsPaused:r,customHeaderActions:o,customFooterActions:a}){let s=useCallback(i=>jsxs("div",{className:"flex gap-2.5 justify-between",children:[i.token&&jsx(xe,{token:i.token}),a?.(i)]}),[a]);return jsx("div",{className:"flex flex-col gap-2.5",onMouseEnter:()=>r(true),onMouseLeave:()=>r(false),children:e.map(i=>jsx(K,{data:i,headerActions:o?.(i),footerActions:s(i),loading:t},i.id))})}function we(){return jsxs("div",{className:"flex flex-col gap-2 bg-default-100 rounded-lg p-3 w-full mx-auto",children:[jsxs("div",{className:"flex items-center gap-3",children:[jsx(Skeleton,{className:"w-10 h-10 rounded-full"}),jsxs("div",{className:"flex flex-col gap-1 flex-1",children:[jsx(Skeleton,{className:"h-4 w-40 rounded-md"}),jsx(Skeleton,{className:"h-3 w-32 rounded-md"})]})]}),jsxs("div",{className:"flex flex-col gap-2",children:[jsx(Skeleton,{className:"h-4 w-full rounded-md"}),jsx(Skeleton,{className:"h-4 w-3/4 rounded-md"}),jsx(Skeleton,{className:"h-4 w-1/2 rounded-md"})]}),jsx(Skeleton,{className:"h-48 w-full rounded-lg"})]})}function j({count:e=3}){return jsx("div",{className:"flex flex-col gap-2",children:Array.from({length:e}).map((t,r)=>jsx(we,{},r))})}var te=()=>{let[e,t]=useState([]),[r,o]=useState(true),[a,s]=useState(false),i=H(),d=useCallback(c=>{t(n=>{let u=n.findIndex(T=>T.id===c.id),m;if(u>=0)m=n.map((T,I)=>I===u?c:T);else {if(a)return n;m=[c,...n];}return m.slice(0,30)}),o(false);},[a]);return useEffect(()=>{let c=i.subscribe("x-monitor-basic",d),n=i.subscribe("x-monitor-token",d);return ()=>{c.unsubscribe(),n.unsubscribe();}},[i,d]),{medias:e,loading:r,isPaused:a,setIsPaused:s}};function Nt({onPauseChange:e,customHeaderActions:t,customFooterActions:r}){let{medias:o,loading:a,isPaused:s,setIsPaused:i}=te();return useEffect(()=>{e?.(s);},[s,e]),a?jsx(j,{count:3}):jsx(Y,{data:o,loading:a,setIsPaused:i,customHeaderActions:t,customFooterActions:r})}function re(){let e=0,t=false,r=null,o=new Map;return {get generation(){return e},connect(){e+=1,t=true;},disconnect(){t=false;},setLocaleTransform(a){r=a;},subscribe(a,s){let i=o.get(a);i||(i=new Set,o.set(a,i)),i.add(s);let d=false;return {unsubscribe(){if(d)return;d=true;let c=o.get(a);c?.delete(s),c&&c.size===0&&o.delete(a);}}},publish(a,s){if(!t)return;let i=r?r(s):s;o.get(a)?.forEach(d=>d(i));}}}function Pt({client:e,children:t}){let r=useMemo(()=>re(),[]);return jsx(N.Provider,{value:{client:e},children:jsxs(h.Provider,{value:r,children:[jsx(At,{client:e}),t]})})}function At({client:e}){let t=useContext(h);return useEffect(()=>{if(!t)return;t.connect();let r=e.subscribeTweetMedia({callback:a=>t.publish("x-monitor-basic",a)}),o=e.subscribeTweetMediaToken({callback:a=>t.publish("x-monitor-token",a)});return ()=>{r.unsubscribe(),o.unsubscribe(),t.disconnect();}},[e,t]),null}
|
|
2
|
+
export{S as MediaImage,N as MediaTrackContext,Pt as MediaTrackProvider,h as MediaTrackRuntimeContext,E as MediaVideo,L as Medias,z as TextExpand,W as Translate,K as TweetItem,D as TweetOriginal,Q as TweetQuote,Z as TweetReply,J as TweetRetweet,we as TweetSkeleton,j as TweetSkeletonList,p as TweetSource,Y as Tweets,Nt as TweetsWidget,U as UserAvatar,B as UserInfo,re as createMediaTrackRuntime,se as translateTweetMedia,Ue as useGenerateTweetMediaMemeMutation,y as useMediaTrackClient,O as useMediaTrackContext,H as useMediaTrackRuntime,_ as useTranslateTweetMediaMutation,te as useTweets};//# sourceMappingURL=index.mjs.map
|
|
3
3
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/tweets/tweet/media/media-image.tsx","../src/components/tweets/tweet/media/media-video.tsx","../src/components/tweets/tweet/media/medias.tsx","../src/components/tweets/tweet/user/user-avatar.tsx","../src/components/tweets/tweet/user/user-info.tsx","../src/context/MediaTrackContext.ts","../src/hooks/useMediaTrackContext.ts","../src/hooks/useMediaTrackClient.ts","../src/hooks/useGenerateTweetMediaMemeMutation.ts","../src/hooks/useTranslateTweetMediaQuery.ts","../src/utils/parseText.tsx","../src/components/tweets/tweet/tools/translate.tsx","../src/components/tweets/tweet/tools/text-expand.tsx","../src/components/tweets/tweet/content/index.tsx","../src/components/tweets/tweet/tweet-source.tsx","../src/components/tweets/tweet/tweet-original.tsx","../src/components/tweets/tweet/tweet-quote.tsx","../src/components/tweets/tweet/tweet-reply.tsx","../src/components/tweets/tweet/tweet-retweet.tsx","../src/components/tweets/tweet/tweet-item.tsx","../src/components/tweets/tweet/tools/tweet-token-button.tsx","../src/components/tweets/tweets.ui.tsx","../src/components/tweets/tweet/tweet-skeleton.tsx","../src/components/tweets/tweets.script.ts","../src/components/tweets/tweets.widget.tsx","../src/providers/MediaTrackProvider.tsx"],"names":["MediaImage","src","isLoaded","setTrue","useBoolean","jsx","Skeleton","MediaVideo","Medias","medias","tweetHref","images","media","videos","renderVideos","video","renderImages","image","Link","jsxs","UserAvatar","url","name","size","fallbackName","useMemo","Avatar","UserInfo","user","renderTimestamp","renderActions","twitterUserUrl","MediaTrackContext","createContext","useMediaTrackContext","context","useContext","useMediaTrackClient","client","useGenerateTweetMediaMemeMutation","options","useMutation","params","translateTweetMedia","targetLanguage","useTranslateTweetMediaMutation","parseText","text","urlRegex","hashtagRegex","symbolRegex","matches","match","matchIndex","m","a","b","parts","lastIndex","key","item","e","hashtagUrl","Translate","data","embed","isTranslate","toggle","t","i18n","useTranslation","isTranslating","translatedText","setTranslatedText","useState","handleTranslate","useCallback","parsedText","Fragment","TranslateIcon","cn","TextExpand","isExpanded","onToggleExpand","renderExpand","ChevronUpIcon","ChevronDownIcon","Content","content","onLoad","ref","useRef","parsedContent","useEffect","current","TweetSource","headerActions","footerActions","indicator","children","setIsExpanded","containerClass","tweet","age","useTickAge","twitterTweetUrl","formatAge","TweetOriginal","TweetQuote","hasSource","TweetReply","sourceTweet","TweetRetweet","TweetItem","loading","TweetSkeleton","tweetType","commonProps","TweetTokenButton","token","color","SafeBigNumber","Button","TweetTokenIcon","formatPercent","ChainIcon","Image","Badge","Tweets","setIsPaused","customHeaderActions","customFooterActions","TweetSkeletonList","count","_","index","useTweets","setMedias","setLoading","isPaused","handleMedia","prevMedias","idx","it","newMedias","subTweet","subTweetToken","TweetsWidget","onPauseChange","MediaTrackProvider"],"mappings":"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","file":"index.mjs","sourcesContent":["import { useBoolean } from \"@liberfi.io/hooks\";\nimport { Skeleton } from \"@liberfi.io/ui\";\n\ntype Props = {\n src: string;\n};\n\n// ------------------------------------------------------------\nexport function MediaImage({ src }: Props) {\n const [isLoaded, { setTrue }] = useBoolean(false);\n if (!src) return null;\n\n return (\n <Skeleton isLoaded={isLoaded} className=\"w-full h-auto\">\n <img\n src={src}\n className=\"w-full h-full object-cover aspect-video\"\n onLoad={() => {\n setTrue();\n }}\n />\n </Skeleton>\n );\n}\n","type Props = {\n src: string;\n};\n\n// ------------------------------------------------------------\nexport function MediaVideo({ src }: Props) {\n if (!src) return null;\n\n return (\n <div className=\"w-full h-full overflow-hidden rounded-md mt-2\">\n <iframe\n className=\"w-full h-full aspect-video\"\n src={src}\n allowFullScreen\n />\n </div>\n );\n}\n","import { Link } from \"@liberfi.io/ui\";\nimport { TweetContentMedia } from \"../../../../types\";\nimport { MediaImage } from \"./media-image\";\nimport { MediaVideo } from \"./media-video\";\n\ntype Props = {\n medias: Array<TweetContentMedia>;\n tweetHref: string;\n};\n\nexport function Medias({ medias, tweetHref }: Props) {\n const images = medias.filter((media) => media.type === \"image\");\n const videos = medias.filter((media) => media.type === \"video\");\n\n const renderVideos = () => {\n if (!videos.length) return null;\n return (\n <div className={`grid grid-cols-1 gap-[1px] overflow-hidden rounded-md`}>\n {videos.map((video) => (\n <MediaVideo key={video.url} src={video.url} />\n ))}\n </div>\n );\n };\n\n const renderImages = () => {\n if (!images.length) return null;\n return (\n <div className={`grid grid-cols-1 gap-[1px] overflow-hidden rounded-md`}>\n {images.map((image) => (\n <Link key={image.url} href={tweetHref} target=\"_blank\">\n <MediaImage src={image.url} />\n </Link>\n ))}\n </div>\n );\n };\n\n return (\n <div className=\"flex flex-col gap-2\">\n {renderVideos()}\n {renderImages()}\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { Avatar, Skeleton } from \"@liberfi.io/ui\";\n\ntype Props = {\n url?: string;\n name?: string;\n size?: number;\n};\n\nexport function UserAvatar({ url, name = \"\", size = 36 }: Props) {\n const fallbackName = useMemo(() => (name ? name.slice(0, 2) : \"N/A\"), [name]);\n\n return (\n <Skeleton\n className=\"flex rounded-full flex-shrink-0\"\n style={{ width: size, height: size }}\n isLoaded={!!url}\n >\n <Avatar\n size=\"md\"\n color=\"primary\"\n radius=\"full\"\n showFallback\n name={fallbackName}\n src={url}\n style={{ width: size, height: size }}\n />\n </Skeleton>\n );\n}\n","import React from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetUser } from \"../../../../types\";\nimport { UserAvatar } from \"./user-avatar\";\n\ntype Props = {\n user: TweetUser;\n renderTimestamp?: React.ReactNode;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function UserInfo({ user, renderTimestamp, renderActions }: Props) {\n return (\n <div className=\"flex items-center justify-between gap-1\">\n <div className=\"flex items-center gap-1\">\n <UserAvatar url={user.avatar} name={user.username} />\n <div className=\"flex flex-col gap-0.5\">\n <div className=\"flex flex-row items-baseline gap-1\">\n <span className=\"text-foreground font-semibold truncate leading-none\">\n {user.username}\n </span>\n {renderTimestamp}\n </div>\n <Link\n target=\"_blank\"\n underline=\"hover\"\n className=\"text-default-500 text-sm leading-none\"\n href={twitterUserUrl(user.screenName ?? user.username)}\n >\n @{user.screenName ?? user.username}\n </Link>\n </div>\n </div>\n {renderActions}\n </div>\n );\n}\n","import { createContext } from \"react\";\nimport { IMediaTrackClient } from \"../types\";\n\nexport interface MediaTrackContextValue {\n client: IMediaTrackClient;\n}\n\nexport const MediaTrackContext = createContext<MediaTrackContextValue>(\n {} as MediaTrackContextValue,\n);\n","import { useContext } from \"react\";\nimport { MediaTrackContext } from \"../context\";\n\nexport function useMediaTrackContext() {\n const context = useContext(MediaTrackContext);\n if (!context) {\n throw new Error(\n \"useMediaTrackContext must be used within a MediaTrackProvider\",\n );\n }\n return context;\n}\n","import { useMediaTrackContext } from \"./useMediaTrackContext\";\n\nexport function useMediaTrackClient() {\n const { client } = useMediaTrackContext();\n return client;\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport { GeneratedMemeInfo, TweetMedia } from \"../types\";\nimport { useMediaTrackClient } from \"./useMediaTrackClient\";\n\nexport function useGenerateTweetMediaMemeMutation(\n options: Omit<\n UseMutationOptions<GeneratedMemeInfo, Error, TweetMedia, string[]>,\n \"mutationFn\"\n > = {},\n) {\n const client = useMediaTrackClient();\n return useMutation({\n mutationFn: async (params: TweetMedia) => client.generateMeme(params),\n ...options,\n });\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport { LocaleCode } from \"@liberfi.io/i18n\";\nimport { IMediaTrackClient, TweetMedia } from \"../types\";\nimport { useMediaTrackClient } from \"./useMediaTrackClient\";\n\nexport interface UseTranslateTweetMediaParams {\n media: TweetMedia;\n targetLanguage: LocaleCode;\n options?: {\n sourceLanguage?: LocaleCode;\n sourceTweet?: boolean;\n };\n}\n\nexport async function translateTweetMedia(\n client: IMediaTrackClient,\n { media, targetLanguage, options }: UseTranslateTweetMediaParams,\n) {\n return await client.translate(media, targetLanguage, options);\n}\n\nexport function useTranslateTweetMediaMutation(\n options: Omit<\n UseMutationOptions<string, Error, UseTranslateTweetMediaParams>,\n \"mutationFn\"\n > = {},\n) {\n const client = useMediaTrackClient();\n return useMutation({\n mutationFn: async (params: UseTranslateTweetMediaParams) =>\n translateTweetMedia(client, params),\n ...options,\n });\n}\n","interface MatchItem {\n index: number;\n length: number;\n text: string;\n type: \"url\" | \"hashtag\" | \"symbol\";\n}\n\nexport function parseText(text: string): (string | React.ReactElement)[] {\n const urlRegex = /(https?:\\/\\/[^\\s]+|www\\.[^\\s]+)/gi;\n const hashtagRegex = /#[\\w]+/g;\n const symbolRegex = /\\$[A-Za-z][A-Za-z0-9_]*/g;\n\n const matches: MatchItem[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = urlRegex.exec(text)) !== null) {\n matches.push({\n index: match.index,\n length: match[0].length,\n text: match[0],\n type: \"url\",\n });\n }\n\n while ((match = hashtagRegex.exec(text)) !== null) {\n const matchIndex = match.index;\n const overlaps = matches.some(\n (m) => matchIndex >= m.index && matchIndex < m.index + m.length,\n );\n if (!overlaps) {\n matches.push({\n index: matchIndex,\n length: match[0].length,\n text: match[0],\n type: \"hashtag\",\n });\n }\n }\n\n while ((match = symbolRegex.exec(text)) !== null) {\n const matchIndex = match.index;\n const overlaps = matches.some(\n (m) => matchIndex >= m.index && matchIndex < m.index + m.length,\n );\n if (!overlaps) {\n matches.push({\n index: matchIndex,\n length: match[0].length,\n text: match[0],\n type: \"symbol\",\n });\n }\n }\n\n matches.sort((a, b) => a.index - b.index);\n\n const parts: (string | React.ReactElement)[] = [];\n let lastIndex = 0;\n let key = 0;\n\n matches.forEach((item) => {\n if (item.index > lastIndex) {\n parts.push(text.slice(lastIndex, item.index));\n }\n\n if (item.type === \"url\") {\n const url = item.text.startsWith(\"http\")\n ? item.text\n : `https://${item.text}`;\n parts.push(\n <a\n key={key++}\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline\"\n onClick={(e) => e.stopPropagation()}\n >\n {item.text}\n </a>,\n );\n } else if (item.type === \"hashtag\") {\n const hashtag = item.text.slice(1); // 移除 #\n const hashtagUrl = `https://x.com/hashtag/${hashtag}`;\n parts.push(\n <a\n key={key++}\n href={hashtagUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline\"\n onClick={(e) => e.stopPropagation()}\n >\n {item.text}\n </a>,\n );\n } else if (item.type === \"symbol\") {\n parts.push(\n <span key={key++} className=\"text-primary\">\n {item.text}\n </span>,\n );\n }\n\n lastIndex = item.index + item.length;\n });\n\n if (lastIndex < text.length) {\n parts.push(text.slice(lastIndex));\n }\n\n return parts.length > 0 ? parts : [text];\n}\n","import React, { MouseEvent, useCallback, useState } from \"react\";\nimport { useBoolean } from \"@liberfi.io/hooks\";\nimport { LocaleCode, useTranslation } from \"@liberfi.io/i18n\";\nimport { cn, Skeleton, TranslateIcon } from \"@liberfi.io/ui\";\nimport { useTranslateTweetMediaMutation } from \"../../../../hooks\";\nimport { TweetMedia } from \"../../../../types\";\nimport { parseText } from \"../../../../utils\";\n\ntype Props = {\n data: TweetMedia;\n embed?: boolean;\n text: string;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function Translate({ data, embed, renderActions }: Props) {\n const [isTranslate, { toggle }] = useBoolean(false);\n\n const { t, i18n } = useTranslation();\n\n const { mutateAsync: translateTweetMedia, isPending: isTranslating } =\n useTranslateTweetMediaMutation();\n\n const [translatedText, setTranslatedText] = useState<\n (string | React.ReactElement)[] | null\n >(null);\n\n const handleTranslate = useCallback(\n async (e: MouseEvent<HTMLDivElement>) => {\n e.stopPropagation();\n toggle();\n if (!translatedText) {\n const text = await translateTweetMedia({\n media: data,\n targetLanguage: i18n.language as LocaleCode,\n options: {\n sourceTweet: embed,\n },\n });\n const parsedText = parseText(text);\n setTranslatedText(parsedText);\n }\n },\n [toggle, translateTweetMedia, data, i18n.language, translatedText],\n );\n\n return (\n <>\n <div className=\"flex items-center gap-1 text-xs\">\n <div\n onClick={handleTranslate}\n className=\"flex items-center gap-0.5 cursor-pointer text-primary hover:text-foreground\"\n >\n <TranslateIcon width=\"14\" height=\"14\" />\n {isTranslate\n ? t(\"mediaTrack.tweets.translate.hide\")\n : t(\"mediaTrack.tweets.translate.show\")}\n </div>\n {renderActions}\n </div>\n <div\n className={cn(!isTranslate && \"hidden\")}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n {isTranslate && (\n <div className=\"bg-content2 rounded-md p-2 text-default-900 text-sm leading-5\">\n {translatedText}\n {isTranslating && <Skeleton className=\"w-full h-4 rounded-md\" />}\n </div>\n )}\n </div>\n </>\n );\n}\n","import { useTranslation } from \"@liberfi.io/i18n\";\nimport { ChevronDownIcon, ChevronUpIcon } from \"@liberfi.io/ui\";\n\ntype Props = {\n isExpanded?: boolean;\n onToggleExpand?: (expanded: boolean) => void;\n};\n\nexport function TextExpand({ isExpanded, onToggleExpand }: Props) {\n const { t } = useTranslation();\n const renderExpand = () => {\n if (isExpanded) {\n return (\n <>\n <ChevronUpIcon\n className=\"border border-current\"\n width=\"12\"\n height=\"12\"\n />\n {t(\"mediaTrack.tweets.collapse\")}\n </>\n );\n }\n\n return (\n <>\n <ChevronDownIcon\n className=\"border border-current\"\n width=\"12\"\n height=\"12\"\n />\n {t(\"mediaTrack.tweets.expand\")}\n </>\n );\n };\n\n if (isExpanded === undefined) return null;\n\n return (\n <div className=\"flex items-center gap-1\">\n <div className=\"w-px h-2.5 bg-line-300\" />\n <button\n onClick={(e) => {\n e.stopPropagation();\n onToggleExpand?.(!isExpanded);\n }}\n className=\"flex items-center text-default-500 hover:text-foreground text-xs\"\n >\n {renderExpand()}\n </button>\n </div>\n );\n}\n","import React, { useEffect, useMemo, useRef } from \"react\";\nimport { parseText } from \"../../../../utils\";\n\ntype Props = {\n content: string;\n isExpanded?: boolean;\n onLoad?: () => void;\n};\n\n// ------------------------------------------------------------\nexport function Content({ content, isExpanded = false, onLoad }: Props) {\n const ref = useRef<HTMLDivElement>(null);\n\n const parsedContent = useMemo(() => parseText(content), [content]);\n\n useEffect(() => {\n const current = ref.current;\n if (!onLoad || !current) return;\n if (current.scrollHeight > current.clientHeight) {\n onLoad?.();\n }\n }, [isExpanded]);\n\n return (\n <div\n ref={ref}\n className={[\n \"text-default-900 text-sm leading-5\",\n !isExpanded ? \"line-clamp-3\" : \"\",\n ].join(\" \")}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n {parsedContent}\n </div>\n );\n}\n","import React, { useMemo, useState } from \"react\";\nimport { useTickAge } from \"@liberfi.io/hooks\";\nimport { cn } from \"@liberfi.io/ui\";\nimport { formatAge, twitterTweetUrl } from \"@liberfi.io/utils\";\nimport { Tweet, TweetMedia } from \"../../../types\";\nimport { Content } from \"./content\";\nimport { Medias } from \"./media\";\nimport { Translate, TextExpand } from \"./tools\";\nimport { UserInfo } from \"./user\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n embed?: boolean;\n indicator?: React.ReactNode;\n children?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetSource({\n data,\n headerActions,\n footerActions,\n embed = false,\n indicator,\n children,\n}: Props) {\n const [isExpanded, setIsExpanded] = useState<boolean | undefined>(undefined);\n\n const containerClass = useMemo(() => {\n return embed\n ? \"bg-default-50 rounded-lg p-3 w-full mx-auto\"\n : \"bg-default-100 hover:bg-default-200 rounded-lg p-3 w-full mx-auto\";\n }, [embed]);\n\n const tweet = useMemo(\n () => (embed ? data.sourceTweet! : data.tweet),\n [data, embed],\n );\n\n const age = useTickAge((tweet as Tweet).timestamp);\n\n return (\n <div\n className={cn(\"flex flex-col gap-1.5 cursor-pointer\", containerClass)}\n onClick={() => {\n window.open(twitterTweetUrl(tweet.tweetId), \"_blank\");\n }}\n >\n {/* -------- USER INFO -------- */}\n <UserInfo\n user={tweet.user}\n renderTimestamp={\n embed ? undefined : (\n <div className=\"text-xs text-primary\">{formatAge(age)}</div>\n )\n }\n renderActions={headerActions}\n />\n\n {/* -------- MESSAGE TYPE INDICATOR -------- */}\n {indicator}\n\n {/* -------- CONTENT -------- */}\n {tweet.content.text && (\n <Content\n content={tweet.content.text}\n isExpanded={isExpanded}\n onLoad={() => setIsExpanded(false)}\n />\n )}\n\n {/* -------- TOOLS -------- */}\n {tweet.content.text && (\n <Translate\n data={data}\n embed={embed}\n text={tweet.content.text}\n renderActions={\n <TextExpand\n isExpanded={isExpanded}\n onToggleExpand={setIsExpanded}\n />\n }\n />\n )}\n\n {/* -------- MEDIA -------- */}\n <div\n className={cn(\n (!tweet.content.medias || tweet.content.medias.length === 0) &&\n \"hidden\",\n )}\n >\n {tweet.content.medias && tweet.content.medias.length > 0 && (\n <Medias\n medias={tweet.content.medias}\n tweetHref={twitterTweetUrl(tweet.tweetId)}\n />\n )}\n </div>\n\n {/* -------- CHILDREN -------- */}\n {children}\n\n {/* -------- Custom ACTIONS -------- */}\n {footerActions}\n </div>\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetOriginal({ data, headerActions, footerActions }: Props) {\n return (\n <TweetSource\n data={data}\n headerActions={headerActions}\n footerActions={footerActions}\n />\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetQuote({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n return (\n <TweetSource\n data={data}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetReply({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n const indicator = useMemo(\n () => (\n <div className=\"flex items-center gap-2 text-sm\">\n <span>Replying to</span>\n {hasSource && (\n <Link\n className=\"text-sm\"\n underline=\"hover\"\n target=\"_blank\"\n href={twitterUserUrl(\n sourceTweet.user.screenName ?? sourceTweet.user.username,\n )}\n >\n @{sourceTweet.user.screenName ?? sourceTweet.user.username}\n </Link>\n )}\n </div>\n ),\n [hasSource, sourceTweet],\n );\n\n return (\n <TweetSource\n data={data}\n indicator={indicator}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetRetweet({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n const indicator = useMemo(\n () => (\n <div className=\"flex items-center gap-2 text-sm\">\n <span>Retweeted by</span>\n {hasSource && (\n <Link\n className=\"text-sm\"\n underline=\"hover\"\n target=\"_blank\"\n href={twitterUserUrl(\n sourceTweet.user.screenName ?? sourceTweet.user.username,\n )}\n >\n @{sourceTweet.user.screenName ?? sourceTweet.user.username}\n </Link>\n )}\n </div>\n ),\n [hasSource, sourceTweet],\n );\n\n return (\n <TweetSource\n data={data}\n indicator={indicator}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React from \"react\";\nimport { Skeleton } from \"@liberfi.io/ui\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetOriginal } from \"./tweet-original\";\nimport { TweetQuote } from \"./tweet-quote\";\nimport { TweetReply } from \"./tweet-reply\";\nimport { TweetRetweet } from \"./tweet-retweet\";\n\ntype Props = {\n data?: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n embed?: boolean;\n children?: React.ReactNode;\n loading?: boolean;\n};\n\n// ------------------------------------------------------------\nexport function TweetItem({\n data,\n headerActions,\n footerActions,\n embed = false,\n children,\n loading = false,\n}: Props) {\n if (loading || !data) {\n return <TweetSkeleton embed={embed} />;\n }\n\n const tweetType = data.tweet.type;\n\n // Render appropriate component based on tweet type\n const renderTweetComponent = () => {\n const commonProps = {\n data,\n headerActions,\n footerActions,\n embed,\n children,\n };\n\n switch (tweetType) {\n case \"reply\":\n return <TweetReply {...commonProps} />;\n case \"retweet\":\n return <TweetRetweet {...commonProps} />;\n case \"quote\":\n return <TweetQuote {...commonProps} />;\n default: // \"original\"\n return <TweetOriginal {...commonProps} />;\n }\n };\n\n return <div className=\"w-full\">{renderTweetComponent()}</div>;\n}\n\n// ------------------------------------------------------------\nfunction TweetSkeleton({ embed = false }: { embed?: boolean }) {\n const containerClass = embed\n ? \"bg-default-50 rounded-lg p-3 w-full mx-auto\"\n : \"bg-default-100 rounded-lg p-3 w-full mx-auto\";\n\n return (\n <div className={[\"flex flex-col gap-2\", containerClass].join(\" \")}>\n {/* User Info Skeleton */}\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"w-10 h-10 rounded-full\" />\n <div className=\"flex flex-col gap-1 flex-1\">\n <Skeleton className=\"h-4 w-24\" />\n <Skeleton className=\"h-3 w-16\" />\n </div>\n <Skeleton className=\"h-3 w-12\" />\n </div>\n\n {/* Content Skeleton */}\n <div className=\"flex flex-col gap-2\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-4 w-1/2\" />\n </div>\n\n {/* Media Skeleton */}\n <Skeleton className=\"h-48 w-full rounded-lg\" />\n\n {/* Actions Skeleton */}\n <div className=\"flex justify-between items-center pt-2\">\n <div className=\"flex gap-4\">\n <Skeleton className=\"h-6 w-16\" />\n <Skeleton className=\"h-6 w-16\" />\n <Skeleton className=\"h-6 w-16\" />\n </div>\n <Skeleton className=\"h-6 w-20\" />\n </div>\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { Avatar, Badge, Button, Image } from \"@liberfi.io/ui\";\nimport { formatPercent, SafeBigNumber } from \"@liberfi.io/utils\";\nimport { MediaToken } from \"../../../../types\";\n\ntype Props = {\n token: MediaToken;\n};\n\nexport function TweetTokenButton({ token }: Props) {\n const color = new SafeBigNumber(token.priceChange ?? \"0\").isPositive()\n ? \"primary\"\n : \"danger\";\n\n return (\n <Button\n color={color}\n variant=\"flat\"\n size=\"sm\"\n radius=\"full\"\n startContent={<TweetTokenIcon token={token} />}\n >\n <span>{token.symbol}</span>\n <span>\n {token.priceChange\n ? formatPercent(Number(token.priceChange) / 100)\n : \"--\"}\n </span>\n </Button>\n );\n}\n\nexport function TweetTokenIcon({ token }: Props) {\n const ChainIcon = useMemo(() => {\n return (\n <Image className=\"w-full h-full\" src={token.image} alt={token.chain} />\n );\n }, [token.chain]);\n\n return (\n <Badge\n className=\"w-2.5 h-2.5 p-0 border\"\n size=\"sm\"\n content={ChainIcon}\n shape=\"circle\"\n placement=\"bottom-right\"\n >\n <Avatar className=\"w-5 h-5\" radius=\"full\" src={token.image} />\n </Badge>\n );\n}\n","import { useCallback } from \"react\";\nimport { TweetMedia } from \"../../types\";\nimport { TweetTokenButton } from \"./tweet/tools/tweet-token-button\";\n// import { TweetTradeButton } from \"./tweet/tools/tweet-trade-button\";\nimport { TweetItem } from \"./tweet/tweet-item\";\n\ntype TweetsProps = {\n data: Array<TweetMedia>;\n loading: boolean;\n setIsPaused: (paused: boolean) => void;\n customHeaderActions?: (item: TweetMedia) => React.ReactNode;\n customFooterActions?: (item: TweetMedia) => React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function Tweets({\n data,\n loading,\n setIsPaused,\n customHeaderActions,\n customFooterActions,\n}: TweetsProps) {\n const footerActions = useCallback(\n (item: TweetMedia) => (\n <div className=\"flex gap-2.5 justify-between\">\n {item.token && <TweetTokenButton token={item.token} />}\n {customFooterActions?.(item)}\n {/* {item.token && <TweetTradeButton token={item.token} />} */}\n </div>\n ),\n [customFooterActions],\n );\n\n return (\n <div\n className=\"flex flex-col gap-2.5\"\n onMouseEnter={() => setIsPaused(true)}\n onMouseLeave={() => setIsPaused(false)}\n >\n {data.map((item: TweetMedia) => (\n <TweetItem\n key={item.id}\n data={item}\n headerActions={customHeaderActions?.(item)}\n footerActions={footerActions(item)}\n loading={loading}\n />\n ))}\n </div>\n );\n}\n","import { Skeleton } from \"@liberfi.io/ui\";\n\n// ------------------------------------------------------------\nexport function TweetSkeleton() {\n return (\n <div className=\"flex flex-col gap-2 bg-default-100 rounded-lg p-3 w-full mx-auto\">\n {/* User Info Skeleton */}\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"w-10 h-10 rounded-full\" />\n <div className=\"flex flex-col gap-1 flex-1\">\n <Skeleton className=\"h-4 w-40 rounded-md\" />\n <Skeleton className=\"h-3 w-32 rounded-md\" />\n </div>\n </div>\n\n {/* Content Skeleton */}\n <div className=\"flex flex-col gap-2\">\n <Skeleton className=\"h-4 w-full rounded-md\" />\n <Skeleton className=\"h-4 w-3/4 rounded-md\" />\n <Skeleton className=\"h-4 w-1/2 rounded-md\" />\n </div>\n\n {/* Media Skeleton */}\n <Skeleton className=\"h-48 w-full rounded-lg\" />\n </div>\n );\n}\n\nexport function TweetSkeletonList({ count = 3 }: { count: number }) {\n return (\n <div className=\"flex flex-col gap-2\">\n {Array.from({ length: count }).map((_, index) => (\n <TweetSkeleton key={index} />\n ))}\n </div>\n );\n}\n","import { useCallback, useEffect, useState } from \"react\";\nimport { useMediaTrackClient } from \"../../hooks\";\nimport { TweetMedia } from \"../../types\";\n\nexport const useTweets = () => {\n const [medias, setMedias] = useState<Array<TweetMedia>>([]);\n const [loading, setLoading] = useState(true);\n const [isPaused, setIsPaused] = useState(false);\n\n const client = useMediaTrackClient();\n\n const handleMedia = useCallback(\n (media: TweetMedia) => {\n setMedias((prevMedias) => {\n const idx = prevMedias.findIndex((it) => it.id === media.id);\n let newMedias: Array<TweetMedia>;\n\n if (idx >= 0) {\n newMedias = prevMedias.map((item, index) =>\n index === idx ? media : item,\n );\n } else {\n if (isPaused) {\n return prevMedias;\n }\n newMedias = [media, ...prevMedias];\n }\n\n return newMedias.slice(0, 30);\n });\n setLoading(false);\n },\n [isPaused],\n );\n\n useEffect(() => {\n const subTweet = client.subscribeTweetMedia({ callback: handleMedia });\n const subTweetToken = client.subscribeTweetMediaToken({\n callback: handleMedia,\n });\n return () => {\n subTweet.unsubscribe();\n subTweetToken.unsubscribe();\n };\n }, [client, handleMedia]);\n\n return { medias, loading, isPaused, setIsPaused };\n};\n","import { useEffect } from \"react\";\nimport { TweetMedia } from \"../../types\";\nimport { TweetSkeletonList } from \"./tweet/tweet-skeleton\";\nimport { useTweets } from \"./tweets.script\";\nimport { Tweets } from \"./tweets.ui\";\n\n// ------------------------------------------------------------\nexport type TweetsWidgetProps = {\n onPauseChange?: (paused: boolean) => void;\n customHeaderActions?: (item: TweetMedia) => React.ReactNode;\n customFooterActions?: (item: TweetMedia) => React.ReactNode;\n};\n\nexport function TweetsWidget({\n onPauseChange,\n customHeaderActions,\n customFooterActions,\n}: TweetsWidgetProps) {\n const { medias, loading, isPaused, setIsPaused } = useTweets();\n\n useEffect(() => {\n onPauseChange?.(isPaused);\n }, [isPaused, onPauseChange]);\n\n if (loading) {\n return <TweetSkeletonList count={3} />;\n }\n\n return (\n <Tweets\n data={medias}\n loading={loading}\n setIsPaused={setIsPaused}\n customHeaderActions={customHeaderActions}\n customFooterActions={customFooterActions}\n />\n );\n}\n","import { PropsWithChildren } from \"react\";\nimport { MediaTrackContext } from \"../context\";\nimport { IMediaTrackClient } from \"../types\";\n\nexport type MediaTrackProviderProps = PropsWithChildren<{\n client: IMediaTrackClient;\n}>;\n\nexport function MediaTrackProvider({\n client,\n children,\n}: MediaTrackProviderProps) {\n return (\n <MediaTrackContext.Provider value={{ client }}>\n {children}\n </MediaTrackContext.Provider>\n );\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/tweets/tweet/media/media-image.tsx","../src/components/tweets/tweet/media/media-video.tsx","../src/components/tweets/tweet/media/medias.tsx","../src/components/tweets/tweet/user/user-avatar.tsx","../src/components/tweets/tweet/user/user-info.tsx","../src/context/MediaTrackContext.ts","../src/context/MediaTrackRuntimeContext.ts","../src/hooks/useMediaTrackContext.ts","../src/hooks/useMediaTrackClient.ts","../src/hooks/useGenerateTweetMediaMemeMutation.ts","../src/hooks/useMediaTrackRuntime.ts","../src/hooks/useTranslateTweetMediaQuery.ts","../src/utils/parseText.tsx","../src/components/tweets/tweet/tools/translate.tsx","../src/components/tweets/tweet/tools/text-expand.tsx","../src/components/tweets/tweet/content/index.tsx","../src/components/tweets/tweet/tweet-source.tsx","../src/components/tweets/tweet/tweet-original.tsx","../src/components/tweets/tweet/tweet-quote.tsx","../src/components/tweets/tweet/tweet-reply.tsx","../src/components/tweets/tweet/tweet-retweet.tsx","../src/components/tweets/tweet/tweet-item.tsx","../src/components/tweets/tweet/tools/tweet-token-button.tsx","../src/components/tweets/tweets.ui.tsx","../src/components/tweets/tweet/tweet-skeleton.tsx","../src/components/tweets/tweets.script.ts","../src/components/tweets/tweets.widget.tsx","../src/runtime/media-track-runtime.ts","../src/providers/MediaTrackProvider.tsx"],"names":["MediaImage","src","isLoaded","setTrue","useBoolean","jsx","Skeleton","MediaVideo","Medias","medias","tweetHref","images","media","videos","renderVideos","video","renderImages","image","Link","jsxs","UserAvatar","url","name","size","fallbackName","useMemo","Avatar","UserInfo","user","renderTimestamp","renderActions","twitterUserUrl","MediaTrackContext","createContext","MediaTrackRuntimeContext","useMediaTrackContext","context","useContext","useMediaTrackClient","client","useGenerateTweetMediaMemeMutation","options","useMutation","params","useMediaTrackRuntime","runtime","translateTweetMedia","targetLanguage","useTranslateTweetMediaMutation","parseText","text","urlRegex","hashtagRegex","symbolRegex","matches","match","matchIndex","a","b","parts","lastIndex","key","item","e","hashtagUrl","Translate","data","embed","isTranslate","toggle","t","i18n","useTranslation","isTranslating","translatedText","setTranslatedText","useState","handleTranslate","useCallback","parsedText","Fragment","TranslateIcon","cn","TextExpand","isExpanded","onToggleExpand","renderExpand","ChevronUpIcon","ChevronDownIcon","Content","content","onLoad","ref","useRef","parsedContent","useEffect","current","TweetSource","headerActions","footerActions","indicator","children","setIsExpanded","containerClass","tweet","age","useTickAge","twitterTweetUrl","formatAge","TweetOriginal","TweetQuote","hasSource","TweetReply","sourceTweet","TweetRetweet","TweetItem","loading","TweetSkeleton","tweetType","commonProps","TweetTokenButton","token","color","SafeBigNumber","Button","TweetTokenIcon","formatPercent","ChainIcon","Image","Badge","Tweets","setIsPaused","customHeaderActions","customFooterActions","TweetSkeletonList","count","_","index","useTweets","setMedias","setLoading","isPaused","handleMedia","prevMedias","idx","it","newMedias","subTweet","subTweetToken","TweetsWidget","onPauseChange","createMediaTrackRuntime","generation","connected","localeTransform","listeners","transform","channel","listener","bucket","unsubscribed","payload","next","MediaTrackProvider","MediaTrackClientBridge","basic"],"mappings":"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","file":"index.mjs","sourcesContent":["import { useBoolean } from \"@liberfi.io/hooks\";\nimport { Skeleton } from \"@liberfi.io/ui\";\n\ntype Props = {\n src: string;\n};\n\n// ------------------------------------------------------------\nexport function MediaImage({ src }: Props) {\n const [isLoaded, { setTrue }] = useBoolean(false);\n if (!src) return null;\n\n return (\n <Skeleton isLoaded={isLoaded} className=\"w-full h-auto\">\n <img\n src={src}\n className=\"w-full h-full object-cover aspect-video\"\n onLoad={() => {\n setTrue();\n }}\n />\n </Skeleton>\n );\n}\n","type Props = {\n src: string;\n};\n\n// ------------------------------------------------------------\nexport function MediaVideo({ src }: Props) {\n if (!src) return null;\n\n return (\n <div className=\"w-full h-full overflow-hidden rounded-md mt-2\">\n <iframe\n className=\"w-full h-full aspect-video\"\n src={src}\n allowFullScreen\n />\n </div>\n );\n}\n","import { Link } from \"@liberfi.io/ui\";\nimport { TweetContentMedia } from \"../../../../types\";\nimport { MediaImage } from \"./media-image\";\nimport { MediaVideo } from \"./media-video\";\n\ntype Props = {\n medias: Array<TweetContentMedia>;\n tweetHref: string;\n};\n\nexport function Medias({ medias, tweetHref }: Props) {\n const images = medias.filter((media) => media.type === \"image\");\n const videos = medias.filter((media) => media.type === \"video\");\n\n const renderVideos = () => {\n if (!videos.length) return null;\n return (\n <div className={`grid grid-cols-1 gap-[1px] overflow-hidden rounded-md`}>\n {videos.map((video) => (\n <MediaVideo key={video.url} src={video.url} />\n ))}\n </div>\n );\n };\n\n const renderImages = () => {\n if (!images.length) return null;\n return (\n <div className={`grid grid-cols-1 gap-[1px] overflow-hidden rounded-md`}>\n {images.map((image) => (\n <Link key={image.url} href={tweetHref} target=\"_blank\">\n <MediaImage src={image.url} />\n </Link>\n ))}\n </div>\n );\n };\n\n return (\n <div className=\"flex flex-col gap-2\">\n {renderVideos()}\n {renderImages()}\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { Avatar, Skeleton } from \"@liberfi.io/ui\";\n\ntype Props = {\n url?: string;\n name?: string;\n size?: number;\n};\n\nexport function UserAvatar({ url, name = \"\", size = 36 }: Props) {\n const fallbackName = useMemo(() => (name ? name.slice(0, 2) : \"N/A\"), [name]);\n\n return (\n <Skeleton\n className=\"flex rounded-full flex-shrink-0\"\n style={{ width: size, height: size }}\n isLoaded={!!url}\n >\n <Avatar\n size=\"md\"\n color=\"primary\"\n radius=\"full\"\n showFallback\n name={fallbackName}\n src={url}\n style={{ width: size, height: size }}\n />\n </Skeleton>\n );\n}\n","import React from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetUser } from \"../../../../types\";\nimport { UserAvatar } from \"./user-avatar\";\n\ntype Props = {\n user: TweetUser;\n renderTimestamp?: React.ReactNode;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function UserInfo({ user, renderTimestamp, renderActions }: Props) {\n return (\n <div className=\"flex items-center justify-between gap-1\">\n <div className=\"flex items-center gap-1\">\n <UserAvatar url={user.avatar} name={user.username} />\n <div className=\"flex flex-col gap-0.5\">\n <div className=\"flex flex-row items-baseline gap-1\">\n <span className=\"text-foreground font-semibold truncate leading-none\">\n {user.username}\n </span>\n {renderTimestamp}\n </div>\n <Link\n target=\"_blank\"\n underline=\"hover\"\n className=\"text-default-500 text-sm leading-none\"\n href={twitterUserUrl(user.screenName ?? user.username)}\n >\n @{user.screenName ?? user.username}\n </Link>\n </div>\n </div>\n {renderActions}\n </div>\n );\n}\n","import { createContext } from \"react\";\nimport { IMediaTrackClient } from \"../types\";\n\nexport interface MediaTrackContextValue {\n client: IMediaTrackClient;\n}\n\nexport const MediaTrackContext = createContext<MediaTrackContextValue>(\n {} as MediaTrackContextValue,\n);\n","import { createContext } from \"react\";\nimport type { TweetMedia } from \"../types\";\nimport type { MediaTrackRuntime } from \"../runtime/media-track-runtime\";\n\nexport const MediaTrackRuntimeContext =\n createContext<MediaTrackRuntime<TweetMedia> | null>(null);\n","import { useContext } from \"react\";\nimport { MediaTrackContext } from \"../context\";\n\nexport function useMediaTrackContext() {\n const context = useContext(MediaTrackContext);\n if (!context) {\n throw new Error(\n \"useMediaTrackContext must be used within a MediaTrackProvider\",\n );\n }\n return context;\n}\n","import { useMediaTrackContext } from \"./useMediaTrackContext\";\n\nexport function useMediaTrackClient() {\n const { client } = useMediaTrackContext();\n return client;\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport { GeneratedMemeInfo, TweetMedia } from \"../types\";\nimport { useMediaTrackClient } from \"./useMediaTrackClient\";\n\nexport function useGenerateTweetMediaMemeMutation(\n options: Omit<\n UseMutationOptions<GeneratedMemeInfo, Error, TweetMedia, string[]>,\n \"mutationFn\"\n > = {},\n) {\n const client = useMediaTrackClient();\n return useMutation({\n mutationFn: async (params: TweetMedia) => client.generateMeme(params),\n ...options,\n });\n}\n","import { useContext } from \"react\";\nimport { MediaTrackRuntimeContext } from \"../context/MediaTrackRuntimeContext\";\n\nexport function useMediaTrackRuntime() {\n const runtime = useContext(MediaTrackRuntimeContext);\n if (!runtime) {\n throw new Error(\n \"useMediaTrackRuntime must be used within a MediaTrackProvider\",\n );\n }\n return runtime;\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport { LocaleCode } from \"@liberfi.io/i18n\";\nimport { IMediaTrackClient, TweetMedia } from \"../types\";\nimport { useMediaTrackClient } from \"./useMediaTrackClient\";\n\nexport interface UseTranslateTweetMediaParams {\n media: TweetMedia;\n targetLanguage: LocaleCode;\n options?: {\n sourceLanguage?: LocaleCode;\n sourceTweet?: boolean;\n };\n}\n\nexport async function translateTweetMedia(\n client: IMediaTrackClient,\n { media, targetLanguage, options }: UseTranslateTweetMediaParams,\n) {\n return await client.translate(media, targetLanguage, options);\n}\n\nexport function useTranslateTweetMediaMutation(\n options: Omit<\n UseMutationOptions<string, Error, UseTranslateTweetMediaParams>,\n \"mutationFn\"\n > = {},\n) {\n const client = useMediaTrackClient();\n return useMutation({\n mutationFn: async (params: UseTranslateTweetMediaParams) =>\n translateTweetMedia(client, params),\n ...options,\n });\n}\n","interface MatchItem {\n index: number;\n length: number;\n text: string;\n type: \"url\" | \"hashtag\" | \"symbol\";\n}\n\nexport function parseText(text: string): (string | React.ReactElement)[] {\n const urlRegex = /(https?:\\/\\/[^\\s]+|www\\.[^\\s]+)/gi;\n const hashtagRegex = /#[\\w]+/g;\n const symbolRegex = /\\$[A-Za-z][A-Za-z0-9_]*/g;\n\n const matches: MatchItem[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = urlRegex.exec(text)) !== null) {\n matches.push({\n index: match.index,\n length: match[0].length,\n text: match[0],\n type: \"url\",\n });\n }\n\n while ((match = hashtagRegex.exec(text)) !== null) {\n const matchIndex = match.index;\n const overlaps = matches.some(\n (m) => matchIndex >= m.index && matchIndex < m.index + m.length,\n );\n if (!overlaps) {\n matches.push({\n index: matchIndex,\n length: match[0].length,\n text: match[0],\n type: \"hashtag\",\n });\n }\n }\n\n while ((match = symbolRegex.exec(text)) !== null) {\n const matchIndex = match.index;\n const overlaps = matches.some(\n (m) => matchIndex >= m.index && matchIndex < m.index + m.length,\n );\n if (!overlaps) {\n matches.push({\n index: matchIndex,\n length: match[0].length,\n text: match[0],\n type: \"symbol\",\n });\n }\n }\n\n matches.sort((a, b) => a.index - b.index);\n\n const parts: (string | React.ReactElement)[] = [];\n let lastIndex = 0;\n let key = 0;\n\n matches.forEach((item) => {\n if (item.index > lastIndex) {\n parts.push(text.slice(lastIndex, item.index));\n }\n\n if (item.type === \"url\") {\n const url = item.text.startsWith(\"http\")\n ? item.text\n : `https://${item.text}`;\n parts.push(\n <a\n key={key++}\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline\"\n onClick={(e) => e.stopPropagation()}\n >\n {item.text}\n </a>,\n );\n } else if (item.type === \"hashtag\") {\n const hashtag = item.text.slice(1); // 移除 #\n const hashtagUrl = `https://x.com/hashtag/${hashtag}`;\n parts.push(\n <a\n key={key++}\n href={hashtagUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline\"\n onClick={(e) => e.stopPropagation()}\n >\n {item.text}\n </a>,\n );\n } else if (item.type === \"symbol\") {\n parts.push(\n <span key={key++} className=\"text-primary\">\n {item.text}\n </span>,\n );\n }\n\n lastIndex = item.index + item.length;\n });\n\n if (lastIndex < text.length) {\n parts.push(text.slice(lastIndex));\n }\n\n return parts.length > 0 ? parts : [text];\n}\n","import React, { MouseEvent, useCallback, useState } from \"react\";\nimport { useBoolean } from \"@liberfi.io/hooks\";\nimport { LocaleCode, useTranslation } from \"@liberfi.io/i18n\";\nimport { cn, Skeleton, TranslateIcon } from \"@liberfi.io/ui\";\nimport { useTranslateTweetMediaMutation } from \"../../../../hooks\";\nimport { TweetMedia } from \"../../../../types\";\nimport { parseText } from \"../../../../utils\";\n\ntype Props = {\n data: TweetMedia;\n embed?: boolean;\n text: string;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function Translate({ data, embed, renderActions }: Props) {\n const [isTranslate, { toggle }] = useBoolean(false);\n\n const { t, i18n } = useTranslation();\n\n const { mutateAsync: translateTweetMedia, isPending: isTranslating } =\n useTranslateTweetMediaMutation();\n\n const [translatedText, setTranslatedText] = useState<\n (string | React.ReactElement)[] | null\n >(null);\n\n const handleTranslate = useCallback(\n async (e: MouseEvent<HTMLDivElement>) => {\n e.stopPropagation();\n toggle();\n if (!translatedText) {\n const text = await translateTweetMedia({\n media: data,\n targetLanguage: i18n.language as LocaleCode,\n options: {\n sourceTweet: embed,\n },\n });\n const parsedText = parseText(text);\n setTranslatedText(parsedText);\n }\n },\n [toggle, translateTweetMedia, data, i18n.language, translatedText, embed],\n );\n\n return (\n <>\n <div className=\"flex items-center gap-1 text-xs\">\n <div\n onClick={handleTranslate}\n className=\"flex items-center gap-0.5 cursor-pointer text-primary hover:text-foreground\"\n >\n <TranslateIcon width=\"14\" height=\"14\" />\n {isTranslate\n ? t(\"mediaTrack.tweets.translate.hide\")\n : t(\"mediaTrack.tweets.translate.show\")}\n </div>\n {renderActions}\n </div>\n <div\n className={cn(!isTranslate && \"hidden\")}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n {isTranslate && (\n <div className=\"bg-content2 rounded-md p-2 text-default-900 text-sm leading-5\">\n {translatedText}\n {isTranslating && <Skeleton className=\"w-full h-4 rounded-md\" />}\n </div>\n )}\n </div>\n </>\n );\n}\n","import { useTranslation } from \"@liberfi.io/i18n\";\nimport { ChevronDownIcon, ChevronUpIcon } from \"@liberfi.io/ui\";\n\ntype Props = {\n isExpanded?: boolean;\n onToggleExpand?: (expanded: boolean) => void;\n};\n\nexport function TextExpand({ isExpanded, onToggleExpand }: Props) {\n const { t } = useTranslation();\n const renderExpand = () => {\n if (isExpanded) {\n return (\n <>\n <ChevronUpIcon\n className=\"border border-current\"\n width=\"12\"\n height=\"12\"\n />\n {t(\"mediaTrack.tweets.collapse\")}\n </>\n );\n }\n\n return (\n <>\n <ChevronDownIcon\n className=\"border border-current\"\n width=\"12\"\n height=\"12\"\n />\n {t(\"mediaTrack.tweets.expand\")}\n </>\n );\n };\n\n if (isExpanded === undefined) return null;\n\n return (\n <div className=\"flex items-center gap-1\">\n <div className=\"w-px h-2.5 bg-line-300\" />\n <button\n onClick={(e) => {\n e.stopPropagation();\n onToggleExpand?.(!isExpanded);\n }}\n className=\"flex items-center text-default-500 hover:text-foreground text-xs\"\n >\n {renderExpand()}\n </button>\n </div>\n );\n}\n","import { useEffect, useMemo, useRef } from \"react\";\nimport { parseText } from \"../../../../utils\";\n\ntype Props = {\n content: string;\n isExpanded?: boolean;\n onLoad?: () => void;\n};\n\n// ------------------------------------------------------------\nexport function Content({ content, isExpanded = false, onLoad }: Props) {\n const ref = useRef<HTMLDivElement>(null);\n\n const parsedContent = useMemo(() => parseText(content), [content]);\n\n useEffect(() => {\n const current = ref.current;\n if (!onLoad || !current) return;\n if (current.scrollHeight > current.clientHeight) {\n onLoad?.();\n }\n }, [isExpanded, onLoad]);\n\n return (\n <div\n ref={ref}\n className={[\n \"text-default-900 text-sm leading-5\",\n !isExpanded ? \"line-clamp-3\" : \"\",\n ].join(\" \")}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n {parsedContent}\n </div>\n );\n}\n","import React, { useMemo, useState } from \"react\";\nimport { useTickAge } from \"@liberfi.io/hooks\";\nimport { cn } from \"@liberfi.io/ui\";\nimport { formatAge, twitterTweetUrl } from \"@liberfi.io/utils\";\nimport { Tweet, TweetMedia } from \"../../../types\";\nimport { Content } from \"./content\";\nimport { Medias } from \"./media\";\nimport { Translate, TextExpand } from \"./tools\";\nimport { UserInfo } from \"./user\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n embed?: boolean;\n indicator?: React.ReactNode;\n children?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetSource({\n data,\n headerActions,\n footerActions,\n embed = false,\n indicator,\n children,\n}: Props) {\n const [isExpanded, setIsExpanded] = useState<boolean | undefined>(undefined);\n\n const containerClass = useMemo(() => {\n return embed\n ? \"bg-default-50 rounded-lg p-3 w-full mx-auto\"\n : \"bg-default-100 hover:bg-default-200 rounded-lg p-3 w-full mx-auto\";\n }, [embed]);\n\n const tweet = useMemo(\n () => (embed ? data.sourceTweet! : data.tweet),\n [data, embed],\n );\n\n const age = useTickAge((tweet as Tweet).timestamp);\n\n return (\n <div\n className={cn(\"flex flex-col gap-1.5 cursor-pointer\", containerClass)}\n onClick={() => {\n window.open(twitterTweetUrl(tweet.tweetId), \"_blank\");\n }}\n >\n {/* -------- USER INFO -------- */}\n <UserInfo\n user={tweet.user}\n renderTimestamp={\n embed ? undefined : (\n <div className=\"text-xs text-primary\">{formatAge(age)}</div>\n )\n }\n renderActions={headerActions}\n />\n\n {/* -------- MESSAGE TYPE INDICATOR -------- */}\n {indicator}\n\n {/* -------- CONTENT -------- */}\n {tweet.content.text && (\n <Content\n content={tweet.content.text}\n isExpanded={isExpanded}\n onLoad={() => setIsExpanded(false)}\n />\n )}\n\n {/* -------- TOOLS -------- */}\n {tweet.content.text && (\n <Translate\n data={data}\n embed={embed}\n text={tweet.content.text}\n renderActions={\n <TextExpand\n isExpanded={isExpanded}\n onToggleExpand={setIsExpanded}\n />\n }\n />\n )}\n\n {/* -------- MEDIA -------- */}\n <div\n className={cn(\n (!tweet.content.medias || tweet.content.medias.length === 0) &&\n \"hidden\",\n )}\n >\n {tweet.content.medias && tweet.content.medias.length > 0 && (\n <Medias\n medias={tweet.content.medias}\n tweetHref={twitterTweetUrl(tweet.tweetId)}\n />\n )}\n </div>\n\n {/* -------- CHILDREN -------- */}\n {children}\n\n {/* -------- Custom ACTIONS -------- */}\n {footerActions}\n </div>\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetOriginal({ data, headerActions, footerActions }: Props) {\n return (\n <TweetSource\n data={data}\n headerActions={headerActions}\n footerActions={footerActions}\n />\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetQuote({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n return (\n <TweetSource\n data={data}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetReply({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n const indicator = useMemo(\n () => (\n <div className=\"flex items-center gap-2 text-sm\">\n <span>Replying to</span>\n {hasSource && (\n <Link\n className=\"text-sm\"\n underline=\"hover\"\n target=\"_blank\"\n href={twitterUserUrl(\n sourceTweet.user.screenName ?? sourceTweet.user.username,\n )}\n >\n @{sourceTweet.user.screenName ?? sourceTweet.user.username}\n </Link>\n )}\n </div>\n ),\n [hasSource, sourceTweet],\n );\n\n return (\n <TweetSource\n data={data}\n indicator={indicator}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetRetweet({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n const indicator = useMemo(\n () => (\n <div className=\"flex items-center gap-2 text-sm\">\n <span>Retweeted by</span>\n {hasSource && (\n <Link\n className=\"text-sm\"\n underline=\"hover\"\n target=\"_blank\"\n href={twitterUserUrl(\n sourceTweet.user.screenName ?? sourceTweet.user.username,\n )}\n >\n @{sourceTweet.user.screenName ?? sourceTweet.user.username}\n </Link>\n )}\n </div>\n ),\n [hasSource, sourceTweet],\n );\n\n return (\n <TweetSource\n data={data}\n indicator={indicator}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React from \"react\";\nimport { Skeleton } from \"@liberfi.io/ui\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetOriginal } from \"./tweet-original\";\nimport { TweetQuote } from \"./tweet-quote\";\nimport { TweetReply } from \"./tweet-reply\";\nimport { TweetRetweet } from \"./tweet-retweet\";\n\ntype Props = {\n data?: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n embed?: boolean;\n children?: React.ReactNode;\n loading?: boolean;\n};\n\n// ------------------------------------------------------------\nexport function TweetItem({\n data,\n headerActions,\n footerActions,\n embed = false,\n children,\n loading = false,\n}: Props) {\n if (loading || !data) {\n return <TweetSkeleton embed={embed} />;\n }\n\n const tweetType = data.tweet.type;\n\n // Render appropriate component based on tweet type\n const renderTweetComponent = () => {\n const commonProps = {\n data,\n headerActions,\n footerActions,\n embed,\n children,\n };\n\n switch (tweetType) {\n case \"reply\":\n return <TweetReply {...commonProps} />;\n case \"retweet\":\n return <TweetRetweet {...commonProps} />;\n case \"quote\":\n return <TweetQuote {...commonProps} />;\n default: // \"original\"\n return <TweetOriginal {...commonProps} />;\n }\n };\n\n return <div className=\"w-full\">{renderTweetComponent()}</div>;\n}\n\n// ------------------------------------------------------------\nfunction TweetSkeleton({ embed = false }: { embed?: boolean }) {\n const containerClass = embed\n ? \"bg-default-50 rounded-lg p-3 w-full mx-auto\"\n : \"bg-default-100 rounded-lg p-3 w-full mx-auto\";\n\n return (\n <div className={[\"flex flex-col gap-2\", containerClass].join(\" \")}>\n {/* User Info Skeleton */}\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"w-10 h-10 rounded-full\" />\n <div className=\"flex flex-col gap-1 flex-1\">\n <Skeleton className=\"h-4 w-24\" />\n <Skeleton className=\"h-3 w-16\" />\n </div>\n <Skeleton className=\"h-3 w-12\" />\n </div>\n\n {/* Content Skeleton */}\n <div className=\"flex flex-col gap-2\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-4 w-1/2\" />\n </div>\n\n {/* Media Skeleton */}\n <Skeleton className=\"h-48 w-full rounded-lg\" />\n\n {/* Actions Skeleton */}\n <div className=\"flex justify-between items-center pt-2\">\n <div className=\"flex gap-4\">\n <Skeleton className=\"h-6 w-16\" />\n <Skeleton className=\"h-6 w-16\" />\n <Skeleton className=\"h-6 w-16\" />\n </div>\n <Skeleton className=\"h-6 w-20\" />\n </div>\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { Avatar, Badge, Button, Image } from \"@liberfi.io/ui\";\nimport { formatPercent, SafeBigNumber } from \"@liberfi.io/utils\";\nimport { MediaToken } from \"../../../../types\";\n\ntype Props = {\n token: MediaToken;\n};\n\nexport function TweetTokenButton({ token }: Props) {\n const color = new SafeBigNumber(token.priceChange ?? \"0\").isPositive()\n ? \"primary\"\n : \"danger\";\n\n return (\n <Button\n color={color}\n variant=\"flat\"\n size=\"sm\"\n radius=\"full\"\n startContent={<TweetTokenIcon token={token} />}\n >\n <span>{token.symbol}</span>\n <span>\n {token.priceChange\n ? formatPercent(Number(token.priceChange) / 100)\n : \"--\"}\n </span>\n </Button>\n );\n}\n\nexport function TweetTokenIcon({ token }: Props) {\n const ChainIcon = useMemo(() => {\n return (\n <Image className=\"w-full h-full\" src={token.image} alt={token.chain} />\n );\n }, [token.chain, token.image]);\n\n return (\n <Badge\n className=\"w-2.5 h-2.5 p-0 border\"\n size=\"sm\"\n content={ChainIcon}\n shape=\"circle\"\n placement=\"bottom-right\"\n >\n <Avatar className=\"w-5 h-5\" radius=\"full\" src={token.image} />\n </Badge>\n );\n}\n","import { useCallback } from \"react\";\nimport { TweetMedia } from \"../../types\";\nimport { TweetTokenButton } from \"./tweet/tools/tweet-token-button\";\n// import { TweetTradeButton } from \"./tweet/tools/tweet-trade-button\";\nimport { TweetItem } from \"./tweet/tweet-item\";\n\ntype TweetsProps = {\n data: Array<TweetMedia>;\n loading: boolean;\n setIsPaused: (paused: boolean) => void;\n customHeaderActions?: (item: TweetMedia) => React.ReactNode;\n customFooterActions?: (item: TweetMedia) => React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function Tweets({\n data,\n loading,\n setIsPaused,\n customHeaderActions,\n customFooterActions,\n}: TweetsProps) {\n const footerActions = useCallback(\n (item: TweetMedia) => (\n <div className=\"flex gap-2.5 justify-between\">\n {item.token && <TweetTokenButton token={item.token} />}\n {customFooterActions?.(item)}\n {/* {item.token && <TweetTradeButton token={item.token} />} */}\n </div>\n ),\n [customFooterActions],\n );\n\n return (\n <div\n className=\"flex flex-col gap-2.5\"\n onMouseEnter={() => setIsPaused(true)}\n onMouseLeave={() => setIsPaused(false)}\n >\n {data.map((item: TweetMedia) => (\n <TweetItem\n key={item.id}\n data={item}\n headerActions={customHeaderActions?.(item)}\n footerActions={footerActions(item)}\n loading={loading}\n />\n ))}\n </div>\n );\n}\n","import { Skeleton } from \"@liberfi.io/ui\";\n\n// ------------------------------------------------------------\nexport function TweetSkeleton() {\n return (\n <div className=\"flex flex-col gap-2 bg-default-100 rounded-lg p-3 w-full mx-auto\">\n {/* User Info Skeleton */}\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"w-10 h-10 rounded-full\" />\n <div className=\"flex flex-col gap-1 flex-1\">\n <Skeleton className=\"h-4 w-40 rounded-md\" />\n <Skeleton className=\"h-3 w-32 rounded-md\" />\n </div>\n </div>\n\n {/* Content Skeleton */}\n <div className=\"flex flex-col gap-2\">\n <Skeleton className=\"h-4 w-full rounded-md\" />\n <Skeleton className=\"h-4 w-3/4 rounded-md\" />\n <Skeleton className=\"h-4 w-1/2 rounded-md\" />\n </div>\n\n {/* Media Skeleton */}\n <Skeleton className=\"h-48 w-full rounded-lg\" />\n </div>\n );\n}\n\nexport function TweetSkeletonList({ count = 3 }: { count: number }) {\n return (\n <div className=\"flex flex-col gap-2\">\n {Array.from({ length: count }).map((_, index) => (\n <TweetSkeleton key={index} />\n ))}\n </div>\n );\n}\n","import { useCallback, useEffect, useState } from \"react\";\nimport { useMediaTrackRuntime } from \"../../hooks/useMediaTrackRuntime\";\nimport { TweetMedia } from \"../../types\";\n\nexport const useTweets = () => {\n const [medias, setMedias] = useState<Array<TweetMedia>>([]);\n const [loading, setLoading] = useState(true);\n const [isPaused, setIsPaused] = useState(false);\n\n const runtime = useMediaTrackRuntime();\n\n const handleMedia = useCallback(\n (media: TweetMedia) => {\n setMedias((prevMedias) => {\n const idx = prevMedias.findIndex((it) => it.id === media.id);\n let newMedias: Array<TweetMedia>;\n\n if (idx >= 0) {\n newMedias = prevMedias.map((item, index) =>\n index === idx ? media : item,\n );\n } else {\n if (isPaused) {\n return prevMedias;\n }\n newMedias = [media, ...prevMedias];\n }\n\n return newMedias.slice(0, 30);\n });\n setLoading(false);\n },\n [isPaused],\n );\n\n useEffect(() => {\n const subTweet = runtime.subscribe(\"x-monitor-basic\", handleMedia);\n const subTweetToken = runtime.subscribe(\"x-monitor-token\", handleMedia);\n return () => {\n subTweet.unsubscribe();\n subTweetToken.unsubscribe();\n };\n }, [runtime, handleMedia]);\n\n return { medias, loading, isPaused, setIsPaused };\n};\n","import { useEffect } from \"react\";\nimport { TweetMedia } from \"../../types\";\nimport { TweetSkeletonList } from \"./tweet/tweet-skeleton\";\nimport { useTweets } from \"./tweets.script\";\nimport { Tweets } from \"./tweets.ui\";\n\n// ------------------------------------------------------------\nexport type TweetsWidgetProps = {\n onPauseChange?: (paused: boolean) => void;\n customHeaderActions?: (item: TweetMedia) => React.ReactNode;\n customFooterActions?: (item: TweetMedia) => React.ReactNode;\n};\n\nexport function TweetsWidget({\n onPauseChange,\n customHeaderActions,\n customFooterActions,\n}: TweetsWidgetProps) {\n const { medias, loading, isPaused, setIsPaused } = useTweets();\n\n useEffect(() => {\n onPauseChange?.(isPaused);\n }, [isPaused, onPauseChange]);\n\n if (loading) {\n return <TweetSkeletonList count={3} />;\n }\n\n return (\n <Tweets\n data={medias}\n loading={loading}\n setIsPaused={setIsPaused}\n customHeaderActions={customHeaderActions}\n customFooterActions={customFooterActions}\n />\n );\n}\n","export type MediaTrackUnsubscribe = () => void;\n\nexport interface MediaTrackSubscription {\n unsubscribe: MediaTrackUnsubscribe;\n}\n\nexport interface MediaTrackRuntime<T = unknown> {\n readonly generation: number;\n connect(): void;\n disconnect(): void;\n setLocaleTransform(transform: ((payload: T) => T) | null): void;\n subscribe(channel: string, listener: (payload: T) => void): MediaTrackSubscription;\n publish(channel: string, payload: T): void;\n}\n\nexport function createMediaTrackRuntime<T = unknown>(): MediaTrackRuntime<T> {\n let generation = 0;\n let connected = false;\n let localeTransform: ((payload: T) => T) | null = null;\n const listeners = new Map<string, Set<(payload: T) => void>>();\n\n return {\n get generation() {\n return generation;\n },\n connect() {\n generation += 1;\n connected = true;\n },\n disconnect() {\n connected = false;\n },\n setLocaleTransform(transform) {\n localeTransform = transform;\n },\n subscribe(channel, listener) {\n let bucket = listeners.get(channel);\n if (!bucket) {\n bucket = new Set();\n listeners.set(channel, bucket);\n }\n bucket.add(listener);\n let unsubscribed = false;\n return {\n unsubscribe() {\n if (unsubscribed) return;\n unsubscribed = true;\n const current = listeners.get(channel);\n current?.delete(listener);\n if (current && current.size === 0) {\n listeners.delete(channel);\n }\n },\n };\n },\n publish(channel, payload) {\n if (!connected) return;\n const next = localeTransform ? localeTransform(payload) : payload;\n listeners.get(channel)?.forEach((listener) => listener(next));\n },\n };\n}\n","import { PropsWithChildren, useContext, useEffect, useMemo } from \"react\";\nimport { MediaTrackContext } from \"../context\";\nimport { MediaTrackRuntimeContext } from \"../context/MediaTrackRuntimeContext\";\nimport { createMediaTrackRuntime } from \"../runtime/media-track-runtime\";\nimport type { IMediaTrackClient, TweetMedia } from \"../types\";\n\nexport type MediaTrackProviderProps = PropsWithChildren<{\n client: IMediaTrackClient;\n}>;\n\nexport function MediaTrackProvider({\n client,\n children,\n}: MediaTrackProviderProps) {\n const runtime = useMemo(() => createMediaTrackRuntime<TweetMedia>(), []);\n\n return (\n <MediaTrackContext.Provider value={{ client }}>\n <MediaTrackRuntimeContext.Provider value={runtime}>\n <MediaTrackClientBridge client={client} />\n {children}\n </MediaTrackRuntimeContext.Provider>\n </MediaTrackContext.Provider>\n );\n}\n\nfunction MediaTrackClientBridge({ client }: { client: IMediaTrackClient }) {\n const runtime = useContext(MediaTrackRuntimeContext);\n useEffect(() => {\n if (!runtime) return;\n runtime.connect();\n const basic = client.subscribeTweetMedia({\n callback: (media) => runtime.publish(\"x-monitor-basic\", media),\n });\n const token = client.subscribeTweetMediaToken({\n callback: (media) => runtime.publish(\"x-monitor-token\", media),\n });\n return () => {\n basic.unsubscribe();\n token.unsubscribe();\n runtime.disconnect();\n };\n }, [client, runtime]);\n return null;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liberfi.io/ui-media-track",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.269",
|
|
4
4
|
"description": "Media Track for Liberfi React SDK",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@chainstream-io/centrifuge": "^1.0.0",
|
|
30
30
|
"tailwind-variants": "^3.1.1",
|
|
31
|
-
"@liberfi.io/hooks": "0.1.
|
|
32
|
-
"@liberfi.io/i18n": "0.1.
|
|
33
|
-
"@liberfi.io/types": "0.4.
|
|
34
|
-
"@liberfi.io/ui": "0.3.
|
|
35
|
-
"@liberfi.io/utils": "0.2.
|
|
31
|
+
"@liberfi.io/hooks": "0.1.266",
|
|
32
|
+
"@liberfi.io/i18n": "0.1.271",
|
|
33
|
+
"@liberfi.io/types": "0.4.74",
|
|
34
|
+
"@liberfi.io/ui": "0.3.74",
|
|
35
|
+
"@liberfi.io/utils": "0.2.73"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@tanstack/react-query": "^5.90.2",
|
|
@@ -41,9 +41,12 @@
|
|
|
41
41
|
"@types/react-dom": "^19.1.9",
|
|
42
42
|
"react": "^19.1.1",
|
|
43
43
|
"react-dom": "^19.1.1",
|
|
44
|
+
"@types/jest": "^29.5.3",
|
|
45
|
+
"jest": "^29.6.1",
|
|
46
|
+
"ts-jest": "^29.4.6",
|
|
44
47
|
"tsup": "^8.5.0",
|
|
45
48
|
"typescript": "^5.9.2",
|
|
46
|
-
"tsconfig": "0.1.
|
|
49
|
+
"tsconfig": "0.1.257"
|
|
47
50
|
},
|
|
48
51
|
"peerDependencies": {
|
|
49
52
|
"@tanstack/react-query": "^5.90.2",
|
|
@@ -53,6 +56,8 @@
|
|
|
53
56
|
"scripts": {
|
|
54
57
|
"dev": "tsup --watch",
|
|
55
58
|
"build": "tsup",
|
|
56
|
-
"
|
|
59
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
60
|
+
"lint": "eslint src",
|
|
61
|
+
"test": "jest --config jest.config.cjs --passWithNoTests --runInBand --detectOpenHandles"
|
|
57
62
|
}
|
|
58
63
|
}
|