@liberfi.io/ui-media-track 0.1.5
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/client/index.d.mts +137 -0
- package/dist/client/index.d.ts +137 -0
- package/dist/client/index.js +2 -0
- package/dist/client/index.js.map +1 -0
- package/dist/client/index.mjs +2 -0
- package/dist/client/index.mjs.map +1 -0
- package/dist/index.d.mts +135 -0
- package/dist/index.d.ts +135 -0
- package/dist/index.js +3 -0
- package/dist/index.js.map +1 -0
- package/dist/index.mjs +3 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +63 -0
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { LocaleCode } from '@liberfi.io/i18n';
|
|
2
|
+
import { API, IMedia, TweetMedia, MediaToken, Tweet, SourceTweet, TweetUser, TweetContent, TweetContentMedia } from '@liberfi.io/types';
|
|
3
|
+
|
|
4
|
+
interface MediaTrackClientOptions {
|
|
5
|
+
endpoint: string;
|
|
6
|
+
streamEndpoint: string;
|
|
7
|
+
accessToken: string | {
|
|
8
|
+
getToken(): Promise<string> | string;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
declare class MediaTrackClient implements API.IMediaTrackClient {
|
|
12
|
+
private client;
|
|
13
|
+
private listenersMap;
|
|
14
|
+
private endpoint;
|
|
15
|
+
private accessToken;
|
|
16
|
+
constructor({ endpoint, streamEndpoint, accessToken, }: MediaTrackClientOptions);
|
|
17
|
+
translate(media: IMedia, targetLanguage: LocaleCode, options?: {
|
|
18
|
+
sourceLanguage?: LocaleCode;
|
|
19
|
+
sourceTweet?: boolean;
|
|
20
|
+
}): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Connect to the media track realtime server
|
|
23
|
+
*/
|
|
24
|
+
connect(): void;
|
|
25
|
+
subscribe<T = any>(channel: string, fn: (data: T) => void): API.ISubscription;
|
|
26
|
+
unsubscribe<T = any>(channel: string, fn: (data: T) => void): void;
|
|
27
|
+
subscribeTweetMedia({ callback, }: API.SubscribeTweetMediasOptions): API.ISubscription;
|
|
28
|
+
subscribeTweetMediaToken({ callback, }: API.SubscribeTweetMediasOptions): API.ISubscription;
|
|
29
|
+
_requestOptions(): Promise<Omit<RequestInit, "method">>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface SubscribedTweetMedia {
|
|
33
|
+
/** media id */
|
|
34
|
+
i: string;
|
|
35
|
+
/** tweet */
|
|
36
|
+
tw: SubscribedTweet;
|
|
37
|
+
/** source tweet, quote or retweet or reply */
|
|
38
|
+
s?: SubscribedSourceTweet;
|
|
39
|
+
/** token type */
|
|
40
|
+
tt?: string;
|
|
41
|
+
/** media token */
|
|
42
|
+
t?: SubscribedMediaToken;
|
|
43
|
+
}
|
|
44
|
+
interface SubscribedMediaToken {
|
|
45
|
+
/** chain slug */
|
|
46
|
+
c: string;
|
|
47
|
+
/** token symbol */
|
|
48
|
+
s: string;
|
|
49
|
+
/** token address */
|
|
50
|
+
a: string;
|
|
51
|
+
/** token image url */
|
|
52
|
+
i?: string;
|
|
53
|
+
/** token latest price in usd */
|
|
54
|
+
p?: string;
|
|
55
|
+
/** token previous price in usd */
|
|
56
|
+
p1?: string;
|
|
57
|
+
}
|
|
58
|
+
interface SubscribedTweetUser {
|
|
59
|
+
/** username */
|
|
60
|
+
s: string;
|
|
61
|
+
/** screen name */
|
|
62
|
+
n?: string;
|
|
63
|
+
/** avatar url */
|
|
64
|
+
a?: string;
|
|
65
|
+
/** tags */
|
|
66
|
+
ut?: Array<string>;
|
|
67
|
+
}
|
|
68
|
+
interface SubscribedTweetContentMedia {
|
|
69
|
+
/** media type */
|
|
70
|
+
t: "image" | "video" | (string & {});
|
|
71
|
+
/** media url */
|
|
72
|
+
u: string;
|
|
73
|
+
}
|
|
74
|
+
interface SubscribedTweetContent {
|
|
75
|
+
/** tweet text */
|
|
76
|
+
t?: string;
|
|
77
|
+
/** tweet medias, e.g. image, video .etc */
|
|
78
|
+
m?: Array<SubscribedTweetContentMedia>;
|
|
79
|
+
}
|
|
80
|
+
interface SubscribedTweet {
|
|
81
|
+
/** tweet type */
|
|
82
|
+
t: "tweet" | "reply" | "quote" | (string & {});
|
|
83
|
+
/** tweet id */
|
|
84
|
+
i: string;
|
|
85
|
+
/** tweet unix timestamp in milliseconds */
|
|
86
|
+
ts: number;
|
|
87
|
+
/** tweet author */
|
|
88
|
+
u: SubscribedTweetUser;
|
|
89
|
+
/** tweet content */
|
|
90
|
+
c: SubscribedTweetContent;
|
|
91
|
+
}
|
|
92
|
+
interface SubscribedSourceTweet {
|
|
93
|
+
/** tweet id */
|
|
94
|
+
i: string;
|
|
95
|
+
/** tweet author */
|
|
96
|
+
u: SubscribedTweetUser;
|
|
97
|
+
/** tweet content */
|
|
98
|
+
c: SubscribedTweetContent;
|
|
99
|
+
}
|
|
100
|
+
interface ResponseData<T> {
|
|
101
|
+
code: string;
|
|
102
|
+
msg: string;
|
|
103
|
+
data: T;
|
|
104
|
+
}
|
|
105
|
+
interface TranslateTweetRequest {
|
|
106
|
+
res_type: string;
|
|
107
|
+
res_id: string;
|
|
108
|
+
source_lang?: LocaleCode;
|
|
109
|
+
target_lang: LocaleCode;
|
|
110
|
+
text: string;
|
|
111
|
+
}
|
|
112
|
+
interface TranslateTweetResult {
|
|
113
|
+
res_type: "tw";
|
|
114
|
+
res_id: string;
|
|
115
|
+
source_lang?: LocaleCode;
|
|
116
|
+
target_lang: LocaleCode;
|
|
117
|
+
target_text: string;
|
|
118
|
+
}
|
|
119
|
+
type TranslateTweetResponse = ResponseData<TranslateTweetResult>;
|
|
120
|
+
|
|
121
|
+
declare function convertFromSubscribedTweetMedia(from: SubscribedTweetMedia): TweetMedia;
|
|
122
|
+
declare function convertFromSubscribedMediaToken(from: SubscribedMediaToken): MediaToken;
|
|
123
|
+
declare function convertFromSubscribedTweet(from: SubscribedTweet): Tweet;
|
|
124
|
+
declare function convertFromSubscribedSourceTweet(from: SubscribedSourceTweet): SourceTweet;
|
|
125
|
+
declare function convertFromSubscribedTweetUser(from: SubscribedTweetUser): TweetUser;
|
|
126
|
+
declare function convertFromSubscribedTweetContent(from: SubscribedTweetContent): TweetContent;
|
|
127
|
+
declare function convertFromSubscribedTweetContentMedia(from: SubscribedTweetContentMedia): TweetContentMedia;
|
|
128
|
+
declare function toTranslateParamsDTO(media: IMedia, targetLanguage: LocaleCode, options?: {
|
|
129
|
+
sourceLanguage?: LocaleCode;
|
|
130
|
+
sourceTweet?: boolean;
|
|
131
|
+
}): TranslateTweetRequest;
|
|
132
|
+
declare function toTranslateTweetParamsDTO(media: TweetMedia, targetLanguage: LocaleCode, options?: {
|
|
133
|
+
sourceLanguage?: LocaleCode;
|
|
134
|
+
sourceTweet?: boolean;
|
|
135
|
+
}): TranslateTweetRequest;
|
|
136
|
+
|
|
137
|
+
export { MediaTrackClient, type MediaTrackClientOptions, type ResponseData, type SubscribedMediaToken, type SubscribedSourceTweet, type SubscribedTweet, type SubscribedTweetContent, type SubscribedTweetContentMedia, type SubscribedTweetMedia, type SubscribedTweetUser, type TranslateTweetRequest, type TranslateTweetResponse, type TranslateTweetResult, convertFromSubscribedMediaToken, convertFromSubscribedSourceTweet, convertFromSubscribedTweet, convertFromSubscribedTweetContent, convertFromSubscribedTweetContentMedia, convertFromSubscribedTweetMedia, convertFromSubscribedTweetUser, toTranslateParamsDTO, toTranslateTweetParamsDTO };
|
|
@@ -0,0 +1,137 @@
|
|
|
1
|
+
import { LocaleCode } from '@liberfi.io/i18n';
|
|
2
|
+
import { API, IMedia, TweetMedia, MediaToken, Tweet, SourceTweet, TweetUser, TweetContent, TweetContentMedia } from '@liberfi.io/types';
|
|
3
|
+
|
|
4
|
+
interface MediaTrackClientOptions {
|
|
5
|
+
endpoint: string;
|
|
6
|
+
streamEndpoint: string;
|
|
7
|
+
accessToken: string | {
|
|
8
|
+
getToken(): Promise<string> | string;
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
declare class MediaTrackClient implements API.IMediaTrackClient {
|
|
12
|
+
private client;
|
|
13
|
+
private listenersMap;
|
|
14
|
+
private endpoint;
|
|
15
|
+
private accessToken;
|
|
16
|
+
constructor({ endpoint, streamEndpoint, accessToken, }: MediaTrackClientOptions);
|
|
17
|
+
translate(media: IMedia, targetLanguage: LocaleCode, options?: {
|
|
18
|
+
sourceLanguage?: LocaleCode;
|
|
19
|
+
sourceTweet?: boolean;
|
|
20
|
+
}): Promise<string>;
|
|
21
|
+
/**
|
|
22
|
+
* Connect to the media track realtime server
|
|
23
|
+
*/
|
|
24
|
+
connect(): void;
|
|
25
|
+
subscribe<T = any>(channel: string, fn: (data: T) => void): API.ISubscription;
|
|
26
|
+
unsubscribe<T = any>(channel: string, fn: (data: T) => void): void;
|
|
27
|
+
subscribeTweetMedia({ callback, }: API.SubscribeTweetMediasOptions): API.ISubscription;
|
|
28
|
+
subscribeTweetMediaToken({ callback, }: API.SubscribeTweetMediasOptions): API.ISubscription;
|
|
29
|
+
_requestOptions(): Promise<Omit<RequestInit, "method">>;
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
interface SubscribedTweetMedia {
|
|
33
|
+
/** media id */
|
|
34
|
+
i: string;
|
|
35
|
+
/** tweet */
|
|
36
|
+
tw: SubscribedTweet;
|
|
37
|
+
/** source tweet, quote or retweet or reply */
|
|
38
|
+
s?: SubscribedSourceTweet;
|
|
39
|
+
/** token type */
|
|
40
|
+
tt?: string;
|
|
41
|
+
/** media token */
|
|
42
|
+
t?: SubscribedMediaToken;
|
|
43
|
+
}
|
|
44
|
+
interface SubscribedMediaToken {
|
|
45
|
+
/** chain slug */
|
|
46
|
+
c: string;
|
|
47
|
+
/** token symbol */
|
|
48
|
+
s: string;
|
|
49
|
+
/** token address */
|
|
50
|
+
a: string;
|
|
51
|
+
/** token image url */
|
|
52
|
+
i?: string;
|
|
53
|
+
/** token latest price in usd */
|
|
54
|
+
p?: string;
|
|
55
|
+
/** token previous price in usd */
|
|
56
|
+
p1?: string;
|
|
57
|
+
}
|
|
58
|
+
interface SubscribedTweetUser {
|
|
59
|
+
/** username */
|
|
60
|
+
s: string;
|
|
61
|
+
/** screen name */
|
|
62
|
+
n?: string;
|
|
63
|
+
/** avatar url */
|
|
64
|
+
a?: string;
|
|
65
|
+
/** tags */
|
|
66
|
+
ut?: Array<string>;
|
|
67
|
+
}
|
|
68
|
+
interface SubscribedTweetContentMedia {
|
|
69
|
+
/** media type */
|
|
70
|
+
t: "image" | "video" | (string & {});
|
|
71
|
+
/** media url */
|
|
72
|
+
u: string;
|
|
73
|
+
}
|
|
74
|
+
interface SubscribedTweetContent {
|
|
75
|
+
/** tweet text */
|
|
76
|
+
t?: string;
|
|
77
|
+
/** tweet medias, e.g. image, video .etc */
|
|
78
|
+
m?: Array<SubscribedTweetContentMedia>;
|
|
79
|
+
}
|
|
80
|
+
interface SubscribedTweet {
|
|
81
|
+
/** tweet type */
|
|
82
|
+
t: "tweet" | "reply" | "quote" | (string & {});
|
|
83
|
+
/** tweet id */
|
|
84
|
+
i: string;
|
|
85
|
+
/** tweet unix timestamp in milliseconds */
|
|
86
|
+
ts: number;
|
|
87
|
+
/** tweet author */
|
|
88
|
+
u: SubscribedTweetUser;
|
|
89
|
+
/** tweet content */
|
|
90
|
+
c: SubscribedTweetContent;
|
|
91
|
+
}
|
|
92
|
+
interface SubscribedSourceTweet {
|
|
93
|
+
/** tweet id */
|
|
94
|
+
i: string;
|
|
95
|
+
/** tweet author */
|
|
96
|
+
u: SubscribedTweetUser;
|
|
97
|
+
/** tweet content */
|
|
98
|
+
c: SubscribedTweetContent;
|
|
99
|
+
}
|
|
100
|
+
interface ResponseData<T> {
|
|
101
|
+
code: string;
|
|
102
|
+
msg: string;
|
|
103
|
+
data: T;
|
|
104
|
+
}
|
|
105
|
+
interface TranslateTweetRequest {
|
|
106
|
+
res_type: string;
|
|
107
|
+
res_id: string;
|
|
108
|
+
source_lang?: LocaleCode;
|
|
109
|
+
target_lang: LocaleCode;
|
|
110
|
+
text: string;
|
|
111
|
+
}
|
|
112
|
+
interface TranslateTweetResult {
|
|
113
|
+
res_type: "tw";
|
|
114
|
+
res_id: string;
|
|
115
|
+
source_lang?: LocaleCode;
|
|
116
|
+
target_lang: LocaleCode;
|
|
117
|
+
target_text: string;
|
|
118
|
+
}
|
|
119
|
+
type TranslateTweetResponse = ResponseData<TranslateTweetResult>;
|
|
120
|
+
|
|
121
|
+
declare function convertFromSubscribedTweetMedia(from: SubscribedTweetMedia): TweetMedia;
|
|
122
|
+
declare function convertFromSubscribedMediaToken(from: SubscribedMediaToken): MediaToken;
|
|
123
|
+
declare function convertFromSubscribedTweet(from: SubscribedTweet): Tweet;
|
|
124
|
+
declare function convertFromSubscribedSourceTweet(from: SubscribedSourceTweet): SourceTweet;
|
|
125
|
+
declare function convertFromSubscribedTweetUser(from: SubscribedTweetUser): TweetUser;
|
|
126
|
+
declare function convertFromSubscribedTweetContent(from: SubscribedTweetContent): TweetContent;
|
|
127
|
+
declare function convertFromSubscribedTweetContentMedia(from: SubscribedTweetContentMedia): TweetContentMedia;
|
|
128
|
+
declare function toTranslateParamsDTO(media: IMedia, targetLanguage: LocaleCode, options?: {
|
|
129
|
+
sourceLanguage?: LocaleCode;
|
|
130
|
+
sourceTweet?: boolean;
|
|
131
|
+
}): TranslateTweetRequest;
|
|
132
|
+
declare function toTranslateTweetParamsDTO(media: TweetMedia, targetLanguage: LocaleCode, options?: {
|
|
133
|
+
sourceLanguage?: LocaleCode;
|
|
134
|
+
sourceTweet?: boolean;
|
|
135
|
+
}): TranslateTweetRequest;
|
|
136
|
+
|
|
137
|
+
export { MediaTrackClient, type MediaTrackClientOptions, type ResponseData, type SubscribedMediaToken, type SubscribedSourceTweet, type SubscribedTweet, type SubscribedTweetContent, type SubscribedTweetContentMedia, type SubscribedTweetMedia, type SubscribedTweetUser, type TranslateTweetRequest, type TranslateTweetResponse, type TranslateTweetResult, convertFromSubscribedMediaToken, convertFromSubscribedSourceTweet, convertFromSubscribedTweet, convertFromSubscribedTweetContent, convertFromSubscribedTweetContentMedia, convertFromSubscribedTweetMedia, convertFromSubscribedTweetUser, toTranslateParamsDTO, toTranslateTweetParamsDTO };
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
'use strict';var centrifuge=require('@chainstream-io/centrifuge'),utils=require('@liberfi.io/utils'),types=require('@liberfi.io/types');function o(e){return {id:e.i,type:"tweet",tokenType:e.tt,token:e.t?S(e.t):void 0,tweet:M(e.tw),sourceTweet:e.s?g(e.s):void 0}}function S(e){let t=e.c==="sol"?types.Chain.SOLANA:utils.chainIdBySlug(e.c);if(!t)throw new Error(`Unsupported chain: ${e.c}`);let r=e.p&&e.p1&&new utils.SafeBigNumber(e.p1).isPositive()?new utils.SafeBigNumber(e.p).minus(e.p1).div(e.p1).times(100).toString():void 0;return {chain:t,address:e.a,symbol:e.s,image:e.i,latestPrice:e.p,previousPrice:e.p1,priceChange:r}}function M(e){return {tweetId:e.i,type:e.t,timestamp:Number(e.ts),user:d(e.u),content:b(e.c)}}function g(e){return {tweetId:e.i,user:d(e.u),content:b(e.c)}}function d(e){return {username:e.s,screenName:e.n,avatar:e.a,tags:e.ut}}function b(e){return {text:e.t,medias:e.m?e.m.map(h).filter(Boolean):void 0}}function h(e){return {type:e.t,url:e.u}}function T(e,t,r){switch(e.type){case "tweet":return m(e,t,r);default:throw new Error(`Unsupported media type: ${e.type}`)}}function m(e,t,r){return {res_type:"tw",res_id:r?.sourceTweet?e.sourceTweet?.tweetId??e.id:e.id,source_lang:r?.sourceLanguage,target_lang:t,text:(r?.sourceTweet?e.sourceTweet?.content.text:e.tweet.content.text)??""}}var p=class{client;listenersMap;endpoint;accessToken;constructor({endpoint:t,streamEndpoint:r,accessToken:n}){this.endpoint=t,this.accessToken=n,this.client=new centrifuge.Centrifuge(r,{getToken:async()=>typeof n=="string"?n:await n.getToken(),debug:true}),this.client.on("connected",()=>{}).on("disconnected",i=>{}).on("error",i=>{}),this.listenersMap=new Map,this.connect();}async translate(t,r,n){let i=await this._requestOptions(),s=T(t,r,n);return (await utils.post(`${this.endpoint}/translation`,s,i)).data.target_text}connect(){this.client.connect();}subscribe(t,r){let n=this.client.getSubscription(t),i=this.listenersMap.get(t);return n||(i=new Set,this.listenersMap.set(t,i),n=this.client.newSubscription(t,{delta:"fossil"}),n.on("subscribed",()=>{}).on("unsubscribed",()=>{}).on("publication",s=>{i?.forEach(c=>c(s.data));}).subscribe()),i?.add(r),new a(this,t,r)}unsubscribe(t,r){let n=this.listenersMap.get(t);if(n&&(n.delete(r),n.size===0)){let i=this.client.getSubscription(t);i&&(i.unsubscribe(),this.client.removeSubscription(i)),this.listenersMap.delete(t);}}subscribeTweetMedia({callback:t}){return this.subscribe("x-monitor-basic",r=>{try{t(o(r));}catch{}})}subscribeTweetMediaToken({callback:t}){return this.subscribe("x-monitor-token",r=>{try{t(o(r));}catch{}})}async _requestOptions(){return {headers:{Authorization:`Bearer ${typeof this.accessToken=="string"?this.accessToken:await this.accessToken.getToken()}`}}}},a=class{constructor(t,r,n){this.client=t;this.channel=r;this.fn=n;}unsubscribe(){this.client.unsubscribe(this.channel,this.fn);}};exports.MediaTrackClient=p;exports.convertFromSubscribedMediaToken=S;exports.convertFromSubscribedSourceTweet=g;exports.convertFromSubscribedTweet=M;exports.convertFromSubscribedTweetContent=b;exports.convertFromSubscribedTweetContentMedia=h;exports.convertFromSubscribedTweetMedia=o;exports.convertFromSubscribedTweetUser=d;exports.toTranslateParamsDTO=T;exports.toTranslateTweetParamsDTO=m;//# sourceMappingURL=index.js.map
|
|
2
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +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","toTranslateParamsDTO","media","targetLanguage","options","toTranslateTweetParamsDTO","MediaTrackClient","endpoint","streamEndpoint","accessToken","Centrifuge","err","requestOptions","params","post","channel","fn","sub","listeners","ctx","it","Subscription","callback","data","client"],"mappings":"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","file":"index.js","sourcesContent":["import { LocaleCode } from \"@liberfi.io/i18n\";\nimport {\n Chain,\n IMedia,\n MediaToken,\n SourceTweet,\n Tweet,\n TweetContent,\n TweetContentMedia,\n TweetMedia,\n TweetUser,\n} from \"@liberfi.io/types\";\nimport { chainIdBySlug, SafeBigNumber } from \"@liberfi.io/utils\";\nimport {\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 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 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 { API } from \"@liberfi.io/types\";\nimport { IMedia } from \"@liberfi.io/types\";\nimport { post } from \"@liberfi.io/utils\";\nimport { SubscribedTweetMedia, TranslateTweetResponse } from \"./types\";\nimport { convertFromSubscribedTweetMedia, toTranslateParamsDTO } 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 API.IMediaTrackClient {\n private client: Centrifuge;\n private listenersMap: Map<string, Set<(data: any) => void>>;\n private endpoint: string;\n private accessToken: MediaTrackClientOptions[\"accessToken\"];\n\n constructor({\n endpoint,\n streamEndpoint,\n accessToken,\n }: MediaTrackClientOptions) {\n this.endpoint = endpoint;\n this.accessToken = accessToken;\n\n this.client = new Centrifuge(streamEndpoint, {\n getToken: async () => {\n return typeof accessToken === \"string\"\n ? accessToken\n : await accessToken.getToken();\n },\n debug: true,\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 this.listenersMap = new Map();\n\n this.connect();\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 post<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 */\n connect() {\n this.client.connect();\n }\n\n subscribe<T = any>(\n channel: string,\n fn: (data: T) => void,\n ): API.ISubscription {\n let sub = this.client.getSubscription(channel);\n let listeners = this.listenersMap.get(channel);\n\n if (!sub) {\n listeners = new Set();\n this.listenersMap.set(channel, listeners);\n\n console.info(\"[media-track] create new sub: \", channel);\n\n sub = this.client.newSubscription(channel, { delta: \"fossil\" });\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 listeners?.forEach((it) => it(ctx.data));\n })\n .subscribe();\n }\n\n listeners?.add(fn);\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 }: API.SubscribeTweetMediasOptions): API.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 }: API.SubscribeTweetMediasOptions): API.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 _requestOptions(): Promise<Omit<RequestInit, \"method\">> {\n const token =\n typeof this.accessToken === \"string\"\n ? this.accessToken\n : await this.accessToken.getToken();\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"]}
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import {Centrifuge}from'@chainstream-io/centrifuge';import {chainIdBySlug,SafeBigNumber,post}from'@liberfi.io/utils';import {Chain}from'@liberfi.io/types';function o(e){return {id:e.i,type:"tweet",tokenType:e.tt,token:e.t?S(e.t):void 0,tweet:M(e.tw),sourceTweet:e.s?g(e.s):void 0}}function S(e){let t=e.c==="sol"?Chain.SOLANA:chainIdBySlug(e.c);if(!t)throw new Error(`Unsupported chain: ${e.c}`);let r=e.p&&e.p1&&new SafeBigNumber(e.p1).isPositive()?new SafeBigNumber(e.p).minus(e.p1).div(e.p1).times(100).toString():void 0;return {chain:t,address:e.a,symbol:e.s,image:e.i,latestPrice:e.p,previousPrice:e.p1,priceChange:r}}function M(e){return {tweetId:e.i,type:e.t,timestamp:Number(e.ts),user:d(e.u),content:b(e.c)}}function g(e){return {tweetId:e.i,user:d(e.u),content:b(e.c)}}function d(e){return {username:e.s,screenName:e.n,avatar:e.a,tags:e.ut}}function b(e){return {text:e.t,medias:e.m?e.m.map(h).filter(Boolean):void 0}}function h(e){return {type:e.t,url:e.u}}function T(e,t,r){switch(e.type){case "tweet":return m(e,t,r);default:throw new Error(`Unsupported media type: ${e.type}`)}}function m(e,t,r){return {res_type:"tw",res_id:r?.sourceTweet?e.sourceTweet?.tweetId??e.id:e.id,source_lang:r?.sourceLanguage,target_lang:t,text:(r?.sourceTweet?e.sourceTweet?.content.text:e.tweet.content.text)??""}}var p=class{client;listenersMap;endpoint;accessToken;constructor({endpoint:t,streamEndpoint:r,accessToken:n}){this.endpoint=t,this.accessToken=n,this.client=new Centrifuge(r,{getToken:async()=>typeof n=="string"?n:await n.getToken(),debug:true}),this.client.on("connected",()=>{}).on("disconnected",i=>{}).on("error",i=>{}),this.listenersMap=new Map,this.connect();}async translate(t,r,n){let i=await this._requestOptions(),s=T(t,r,n);return (await post(`${this.endpoint}/translation`,s,i)).data.target_text}connect(){this.client.connect();}subscribe(t,r){let n=this.client.getSubscription(t),i=this.listenersMap.get(t);return n||(i=new Set,this.listenersMap.set(t,i),n=this.client.newSubscription(t,{delta:"fossil"}),n.on("subscribed",()=>{}).on("unsubscribed",()=>{}).on("publication",s=>{i?.forEach(c=>c(s.data));}).subscribe()),i?.add(r),new a(this,t,r)}unsubscribe(t,r){let n=this.listenersMap.get(t);if(n&&(n.delete(r),n.size===0)){let i=this.client.getSubscription(t);i&&(i.unsubscribe(),this.client.removeSubscription(i)),this.listenersMap.delete(t);}}subscribeTweetMedia({callback:t}){return this.subscribe("x-monitor-basic",r=>{try{t(o(r));}catch{}})}subscribeTweetMediaToken({callback:t}){return this.subscribe("x-monitor-token",r=>{try{t(o(r));}catch{}})}async _requestOptions(){return {headers:{Authorization:`Bearer ${typeof this.accessToken=="string"?this.accessToken:await this.accessToken.getToken()}`}}}},a=class{constructor(t,r,n){this.client=t;this.channel=r;this.fn=n;}unsubscribe(){this.client.unsubscribe(this.channel,this.fn);}};export{p as MediaTrackClient,S as convertFromSubscribedMediaToken,g as convertFromSubscribedSourceTweet,M as convertFromSubscribedTweet,b as convertFromSubscribedTweetContent,h as convertFromSubscribedTweetContentMedia,o as convertFromSubscribedTweetMedia,d as convertFromSubscribedTweetUser,T as toTranslateParamsDTO,m as toTranslateTweetParamsDTO};//# sourceMappingURL=index.mjs.map
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +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","toTranslateParamsDTO","media","targetLanguage","options","toTranslateTweetParamsDTO","MediaTrackClient","endpoint","streamEndpoint","accessToken","Centrifuge","err","requestOptions","params","post","channel","fn","sub","listeners","ctx","it","Subscription","callback","data","client"],"mappings":"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","file":"index.mjs","sourcesContent":["import { LocaleCode } from \"@liberfi.io/i18n\";\nimport {\n Chain,\n IMedia,\n MediaToken,\n SourceTweet,\n Tweet,\n TweetContent,\n TweetContentMedia,\n TweetMedia,\n TweetUser,\n} from \"@liberfi.io/types\";\nimport { chainIdBySlug, SafeBigNumber } from \"@liberfi.io/utils\";\nimport {\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 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 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 { API } from \"@liberfi.io/types\";\nimport { IMedia } from \"@liberfi.io/types\";\nimport { post } from \"@liberfi.io/utils\";\nimport { SubscribedTweetMedia, TranslateTweetResponse } from \"./types\";\nimport { convertFromSubscribedTweetMedia, toTranslateParamsDTO } 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 API.IMediaTrackClient {\n private client: Centrifuge;\n private listenersMap: Map<string, Set<(data: any) => void>>;\n private endpoint: string;\n private accessToken: MediaTrackClientOptions[\"accessToken\"];\n\n constructor({\n endpoint,\n streamEndpoint,\n accessToken,\n }: MediaTrackClientOptions) {\n this.endpoint = endpoint;\n this.accessToken = accessToken;\n\n this.client = new Centrifuge(streamEndpoint, {\n getToken: async () => {\n return typeof accessToken === \"string\"\n ? accessToken\n : await accessToken.getToken();\n },\n debug: true,\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 this.listenersMap = new Map();\n\n this.connect();\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 post<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 */\n connect() {\n this.client.connect();\n }\n\n subscribe<T = any>(\n channel: string,\n fn: (data: T) => void,\n ): API.ISubscription {\n let sub = this.client.getSubscription(channel);\n let listeners = this.listenersMap.get(channel);\n\n if (!sub) {\n listeners = new Set();\n this.listenersMap.set(channel, listeners);\n\n console.info(\"[media-track] create new sub: \", channel);\n\n sub = this.client.newSubscription(channel, { delta: \"fossil\" });\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 listeners?.forEach((it) => it(ctx.data));\n })\n .subscribe();\n }\n\n listeners?.add(fn);\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 }: API.SubscribeTweetMediasOptions): API.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 }: API.SubscribeTweetMediasOptions): API.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 _requestOptions(): Promise<Omit<RequestInit, \"method\">> {\n const token =\n typeof this.accessToken === \"string\"\n ? this.accessToken\n : await this.accessToken.getToken();\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
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as _liberfi_io_types from '@liberfi.io/types';
|
|
3
|
+
import { TweetContentMedia, TweetUser, TweetMedia, Tweet, SourceTweet, API } from '@liberfi.io/types';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import React__default, { PropsWithChildren } from 'react';
|
|
6
|
+
|
|
7
|
+
declare global {
|
|
8
|
+
interface Window {
|
|
9
|
+
__LIBERFI_VERSION__?: {
|
|
10
|
+
[key: string]: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
declare const _default: "0.1.4";
|
|
15
|
+
|
|
16
|
+
type Props$c = {
|
|
17
|
+
src: string;
|
|
18
|
+
};
|
|
19
|
+
declare function MediaImage({ src }: Props$c): react_jsx_runtime.JSX.Element | null;
|
|
20
|
+
|
|
21
|
+
type Props$b = {
|
|
22
|
+
src: string;
|
|
23
|
+
};
|
|
24
|
+
declare function MediaVideo({ src }: Props$b): react_jsx_runtime.JSX.Element | null;
|
|
25
|
+
|
|
26
|
+
type Props$a = {
|
|
27
|
+
medias: Array<TweetContentMedia>;
|
|
28
|
+
tweetHref: string;
|
|
29
|
+
};
|
|
30
|
+
declare function Medias({ medias, tweetHref }: Props$a): react_jsx_runtime.JSX.Element;
|
|
31
|
+
|
|
32
|
+
type Props$9 = {
|
|
33
|
+
user: TweetUser;
|
|
34
|
+
renderTimestamp?: React__default.ReactNode;
|
|
35
|
+
renderActions?: React__default.ReactNode;
|
|
36
|
+
};
|
|
37
|
+
declare function UserInfo({ user, renderTimestamp, renderActions }: Props$9): react_jsx_runtime.JSX.Element;
|
|
38
|
+
|
|
39
|
+
type Props$8 = {
|
|
40
|
+
url?: string;
|
|
41
|
+
name?: string;
|
|
42
|
+
size?: number;
|
|
43
|
+
};
|
|
44
|
+
declare function UserAvatar({ url, name, size }: Props$8): react_jsx_runtime.JSX.Element;
|
|
45
|
+
|
|
46
|
+
type Props$7 = {
|
|
47
|
+
text: string;
|
|
48
|
+
renderActions?: React__default.ReactNode;
|
|
49
|
+
};
|
|
50
|
+
declare function Translate({ text, renderActions }: Props$7): react_jsx_runtime.JSX.Element;
|
|
51
|
+
|
|
52
|
+
type Props$6 = {
|
|
53
|
+
isExpanded?: boolean;
|
|
54
|
+
onToggleExpand?: (expanded: boolean) => void;
|
|
55
|
+
};
|
|
56
|
+
declare function TextExpand({ isExpanded, onToggleExpand }: Props$6): react_jsx_runtime.JSX.Element | null;
|
|
57
|
+
|
|
58
|
+
type Props$5 = {
|
|
59
|
+
data?: TweetMedia;
|
|
60
|
+
renderActions?: React__default.ReactNode;
|
|
61
|
+
embed?: boolean;
|
|
62
|
+
children?: React__default.ReactNode;
|
|
63
|
+
loading?: boolean;
|
|
64
|
+
};
|
|
65
|
+
declare function TweetItem({ data, renderActions, embed, children, loading, }: Props$5): react_jsx_runtime.JSX.Element;
|
|
66
|
+
|
|
67
|
+
type Props$4 = {
|
|
68
|
+
data: Tweet | SourceTweet;
|
|
69
|
+
renderActions?: React__default.ReactNode;
|
|
70
|
+
embed?: boolean;
|
|
71
|
+
indicator?: React__default.ReactNode;
|
|
72
|
+
children?: React__default.ReactNode;
|
|
73
|
+
};
|
|
74
|
+
declare function TweetSource({ data, renderActions, embed, indicator, children, }: Props$4): react_jsx_runtime.JSX.Element;
|
|
75
|
+
|
|
76
|
+
type Props$3 = {
|
|
77
|
+
data: TweetMedia;
|
|
78
|
+
renderActions?: React__default.ReactNode;
|
|
79
|
+
};
|
|
80
|
+
declare function TweetReply({ data, renderActions }: Props$3): react_jsx_runtime.JSX.Element;
|
|
81
|
+
|
|
82
|
+
type Props$2 = {
|
|
83
|
+
data: TweetMedia;
|
|
84
|
+
renderActions?: React__default.ReactNode;
|
|
85
|
+
};
|
|
86
|
+
declare function TweetRetweet({ data, renderActions }: Props$2): react_jsx_runtime.JSX.Element;
|
|
87
|
+
|
|
88
|
+
type Props$1 = {
|
|
89
|
+
data: TweetMedia;
|
|
90
|
+
renderActions?: React__default.ReactNode;
|
|
91
|
+
};
|
|
92
|
+
declare function TweetQuote({ data, renderActions }: Props$1): react_jsx_runtime.JSX.Element;
|
|
93
|
+
|
|
94
|
+
type Props = {
|
|
95
|
+
data: TweetMedia;
|
|
96
|
+
renderActions?: React__default.ReactNode;
|
|
97
|
+
};
|
|
98
|
+
declare function TweetOriginal({ data, renderActions }: Props): react_jsx_runtime.JSX.Element;
|
|
99
|
+
|
|
100
|
+
type TweetsProps = {
|
|
101
|
+
data: Array<TweetMedia>;
|
|
102
|
+
loading: boolean;
|
|
103
|
+
setIsPaused: (paused: boolean) => void;
|
|
104
|
+
};
|
|
105
|
+
declare function Tweets({ data, loading, setIsPaused }: TweetsProps): react_jsx_runtime.JSX.Element;
|
|
106
|
+
|
|
107
|
+
declare function TweetsWidget(): react_jsx_runtime.JSX.Element;
|
|
108
|
+
|
|
109
|
+
declare const useTweets: () => {
|
|
110
|
+
medias: TweetMedia[];
|
|
111
|
+
loading: boolean;
|
|
112
|
+
isPaused: boolean;
|
|
113
|
+
setIsPaused: React.Dispatch<React.SetStateAction<boolean>>;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
declare function TweetSkeleton(): react_jsx_runtime.JSX.Element;
|
|
117
|
+
declare function TweetSkeletonList({ count }: {
|
|
118
|
+
count: number;
|
|
119
|
+
}): react_jsx_runtime.JSX.Element;
|
|
120
|
+
|
|
121
|
+
interface MediaTrackContextValue {
|
|
122
|
+
client: API.IMediaTrackClient;
|
|
123
|
+
}
|
|
124
|
+
declare const MediaTrackContext: React.Context<MediaTrackContextValue>;
|
|
125
|
+
|
|
126
|
+
declare function useMediaTrackClient(): _liberfi_io_types.IMediaTrackClient;
|
|
127
|
+
|
|
128
|
+
declare function useMediaTrackContext(): MediaTrackContextValue;
|
|
129
|
+
|
|
130
|
+
type MediaTrackProviderProps = PropsWithChildren<{
|
|
131
|
+
client: API.IMediaTrackClient;
|
|
132
|
+
}>;
|
|
133
|
+
declare function MediaTrackProvider({ client, children, }: MediaTrackProviderProps): react_jsx_runtime.JSX.Element;
|
|
134
|
+
|
|
135
|
+
export { MediaImage, MediaTrackContext, type MediaTrackContextValue, MediaTrackProvider, type MediaTrackProviderProps, MediaVideo, Medias, TextExpand, Translate, TweetItem, TweetOriginal, TweetQuote, TweetReply, TweetRetweet, TweetSkeleton, TweetSkeletonList, TweetSource, Tweets, TweetsWidget, UserAvatar, UserInfo, useMediaTrackClient, useMediaTrackContext, useTweets, _default as version };
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
import * as react_jsx_runtime from 'react/jsx-runtime';
|
|
2
|
+
import * as _liberfi_io_types from '@liberfi.io/types';
|
|
3
|
+
import { TweetContentMedia, TweetUser, TweetMedia, Tweet, SourceTweet, API } from '@liberfi.io/types';
|
|
4
|
+
import * as React from 'react';
|
|
5
|
+
import React__default, { PropsWithChildren } from 'react';
|
|
6
|
+
|
|
7
|
+
declare global {
|
|
8
|
+
interface Window {
|
|
9
|
+
__LIBERFI_VERSION__?: {
|
|
10
|
+
[key: string]: string;
|
|
11
|
+
};
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
declare const _default: "0.1.4";
|
|
15
|
+
|
|
16
|
+
type Props$c = {
|
|
17
|
+
src: string;
|
|
18
|
+
};
|
|
19
|
+
declare function MediaImage({ src }: Props$c): react_jsx_runtime.JSX.Element | null;
|
|
20
|
+
|
|
21
|
+
type Props$b = {
|
|
22
|
+
src: string;
|
|
23
|
+
};
|
|
24
|
+
declare function MediaVideo({ src }: Props$b): react_jsx_runtime.JSX.Element | null;
|
|
25
|
+
|
|
26
|
+
type Props$a = {
|
|
27
|
+
medias: Array<TweetContentMedia>;
|
|
28
|
+
tweetHref: string;
|
|
29
|
+
};
|
|
30
|
+
declare function Medias({ medias, tweetHref }: Props$a): react_jsx_runtime.JSX.Element;
|
|
31
|
+
|
|
32
|
+
type Props$9 = {
|
|
33
|
+
user: TweetUser;
|
|
34
|
+
renderTimestamp?: React__default.ReactNode;
|
|
35
|
+
renderActions?: React__default.ReactNode;
|
|
36
|
+
};
|
|
37
|
+
declare function UserInfo({ user, renderTimestamp, renderActions }: Props$9): react_jsx_runtime.JSX.Element;
|
|
38
|
+
|
|
39
|
+
type Props$8 = {
|
|
40
|
+
url?: string;
|
|
41
|
+
name?: string;
|
|
42
|
+
size?: number;
|
|
43
|
+
};
|
|
44
|
+
declare function UserAvatar({ url, name, size }: Props$8): react_jsx_runtime.JSX.Element;
|
|
45
|
+
|
|
46
|
+
type Props$7 = {
|
|
47
|
+
text: string;
|
|
48
|
+
renderActions?: React__default.ReactNode;
|
|
49
|
+
};
|
|
50
|
+
declare function Translate({ text, renderActions }: Props$7): react_jsx_runtime.JSX.Element;
|
|
51
|
+
|
|
52
|
+
type Props$6 = {
|
|
53
|
+
isExpanded?: boolean;
|
|
54
|
+
onToggleExpand?: (expanded: boolean) => void;
|
|
55
|
+
};
|
|
56
|
+
declare function TextExpand({ isExpanded, onToggleExpand }: Props$6): react_jsx_runtime.JSX.Element | null;
|
|
57
|
+
|
|
58
|
+
type Props$5 = {
|
|
59
|
+
data?: TweetMedia;
|
|
60
|
+
renderActions?: React__default.ReactNode;
|
|
61
|
+
embed?: boolean;
|
|
62
|
+
children?: React__default.ReactNode;
|
|
63
|
+
loading?: boolean;
|
|
64
|
+
};
|
|
65
|
+
declare function TweetItem({ data, renderActions, embed, children, loading, }: Props$5): react_jsx_runtime.JSX.Element;
|
|
66
|
+
|
|
67
|
+
type Props$4 = {
|
|
68
|
+
data: Tweet | SourceTweet;
|
|
69
|
+
renderActions?: React__default.ReactNode;
|
|
70
|
+
embed?: boolean;
|
|
71
|
+
indicator?: React__default.ReactNode;
|
|
72
|
+
children?: React__default.ReactNode;
|
|
73
|
+
};
|
|
74
|
+
declare function TweetSource({ data, renderActions, embed, indicator, children, }: Props$4): react_jsx_runtime.JSX.Element;
|
|
75
|
+
|
|
76
|
+
type Props$3 = {
|
|
77
|
+
data: TweetMedia;
|
|
78
|
+
renderActions?: React__default.ReactNode;
|
|
79
|
+
};
|
|
80
|
+
declare function TweetReply({ data, renderActions }: Props$3): react_jsx_runtime.JSX.Element;
|
|
81
|
+
|
|
82
|
+
type Props$2 = {
|
|
83
|
+
data: TweetMedia;
|
|
84
|
+
renderActions?: React__default.ReactNode;
|
|
85
|
+
};
|
|
86
|
+
declare function TweetRetweet({ data, renderActions }: Props$2): react_jsx_runtime.JSX.Element;
|
|
87
|
+
|
|
88
|
+
type Props$1 = {
|
|
89
|
+
data: TweetMedia;
|
|
90
|
+
renderActions?: React__default.ReactNode;
|
|
91
|
+
};
|
|
92
|
+
declare function TweetQuote({ data, renderActions }: Props$1): react_jsx_runtime.JSX.Element;
|
|
93
|
+
|
|
94
|
+
type Props = {
|
|
95
|
+
data: TweetMedia;
|
|
96
|
+
renderActions?: React__default.ReactNode;
|
|
97
|
+
};
|
|
98
|
+
declare function TweetOriginal({ data, renderActions }: Props): react_jsx_runtime.JSX.Element;
|
|
99
|
+
|
|
100
|
+
type TweetsProps = {
|
|
101
|
+
data: Array<TweetMedia>;
|
|
102
|
+
loading: boolean;
|
|
103
|
+
setIsPaused: (paused: boolean) => void;
|
|
104
|
+
};
|
|
105
|
+
declare function Tweets({ data, loading, setIsPaused }: TweetsProps): react_jsx_runtime.JSX.Element;
|
|
106
|
+
|
|
107
|
+
declare function TweetsWidget(): react_jsx_runtime.JSX.Element;
|
|
108
|
+
|
|
109
|
+
declare const useTweets: () => {
|
|
110
|
+
medias: TweetMedia[];
|
|
111
|
+
loading: boolean;
|
|
112
|
+
isPaused: boolean;
|
|
113
|
+
setIsPaused: React.Dispatch<React.SetStateAction<boolean>>;
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
declare function TweetSkeleton(): react_jsx_runtime.JSX.Element;
|
|
117
|
+
declare function TweetSkeletonList({ count }: {
|
|
118
|
+
count: number;
|
|
119
|
+
}): react_jsx_runtime.JSX.Element;
|
|
120
|
+
|
|
121
|
+
interface MediaTrackContextValue {
|
|
122
|
+
client: API.IMediaTrackClient;
|
|
123
|
+
}
|
|
124
|
+
declare const MediaTrackContext: React.Context<MediaTrackContextValue>;
|
|
125
|
+
|
|
126
|
+
declare function useMediaTrackClient(): _liberfi_io_types.IMediaTrackClient;
|
|
127
|
+
|
|
128
|
+
declare function useMediaTrackContext(): MediaTrackContextValue;
|
|
129
|
+
|
|
130
|
+
type MediaTrackProviderProps = PropsWithChildren<{
|
|
131
|
+
client: API.IMediaTrackClient;
|
|
132
|
+
}>;
|
|
133
|
+
declare function MediaTrackProvider({ client, children, }: MediaTrackProviderProps): react_jsx_runtime.JSX.Element;
|
|
134
|
+
|
|
135
|
+
export { MediaImage, MediaTrackContext, type MediaTrackContextValue, MediaTrackProvider, type MediaTrackProviderProps, MediaVideo, Medias, TextExpand, Translate, TweetItem, TweetOriginal, TweetQuote, TweetReply, TweetRetweet, TweetSkeleton, TweetSkeletonList, TweetSource, Tweets, TweetsWidget, UserAvatar, UserInfo, useMediaTrackClient, useMediaTrackContext, useTweets, _default as version };
|
package/dist/index.js
ADDED
|
@@ -0,0 +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');typeof window<"u"&&(window.__LIBERFI_VERSION__=window.__LIBERFI_VERSION__||{},window.__LIBERFI_VERSION__["@liberfi.io/ui-media-track"]="0.1.4");var we="0.1.4";function U({src:e}){let[r,{setTrue:t}]=hooks.useBoolean(false);return e?jsxRuntime.jsx(ui.Skeleton,{isLoaded:r,className:"w-full h-auto",children:jsxRuntime.jsx("img",{src:e,className:"w-full h-full object-cover aspect-video",onLoad:()=>{t();}})}):null}function F({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 O({medias:e,tweetHref:r}){let t=e.filter(i=>i.type==="image"),n=e.filter(i=>i.type==="video"),o=()=>n.length?jsxRuntime.jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:n.map(i=>jsxRuntime.jsx(F,{src:i.url},i.url))}):null,s=()=>t.length?jsxRuntime.jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:t.map(i=>jsxRuntime.jsx(ui.Link,{href:r,target:"_blank",children:jsxRuntime.jsx(U,{src:i.url})},i.url))}):null;return jsxRuntime.jsxs("div",{className:"flex flex-col gap-2",children:[o(),s()]})}function H({url:e,name:r="",size:t=36}){let n=react.useMemo(()=>r?r.slice(0,2):"N/A",[r]);return jsxRuntime.jsx(ui.Skeleton,{className:"flex rounded-full flex-shrink-0",style:{width:t,height:t},isLoaded:!!e,children:jsxRuntime.jsx(ui.Avatar,{size:"md",color:"primary",radius:"full",showFallback:true,name:n,src:e,style:{width:t,height:t}})})}function $({user:e,renderTimestamp:r,renderActions:t}){return jsxRuntime.jsxs("div",{className:"flex items-center gap-1",children:[jsxRuntime.jsx(H,{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}),r]}),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]})]}),t]})}function D({text:e,renderActions:r}){let[t,{toggle:n}]=hooks.useBoolean(false),{t:o}=i18n.useTranslation(),s=()=>t?jsxRuntime.jsx("div",{className:"bg-content2 rounded-md p-2 text-default-900 text-sm leading-5",children:e}):null;return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-1 text-xs",children:[jsxRuntime.jsxs("div",{onClick:i=>{i.stopPropagation(),n();},className:"flex items-center gap-0.5 cursor-pointer text-primary hover:text-foreground",children:[jsxRuntime.jsx(ui.TranslateIcon,{width:"14",height:"14"}),o(t?"mediaTrack.tweets.translate.hide":"mediaTrack.tweets.translate.show")]}),r]}),jsxRuntime.jsx("div",{className:ui.clsx(!t&&"hidden"),onClick:i=>{i.stopPropagation();},children:s()})]})}function Z({isExpanded:e,onToggleExpand:r}){let{t}=i18n.useTranslation(),n=()=>e?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(ui.ChevronUpIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",t("mediaTrack.tweets.collapse")]}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(ui.ChevronDownIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",t("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:o=>{o.stopPropagation(),r?.(!e);},className:"flex items-center text-default-500 hover:text-foreground text-xs",children:n()})]})}function q(e){let r=/(https?:\/\/[^\s]+|www\.[^\s]+)/gi,t=/#[\w]+/g,n=/\$[A-Za-z][A-Za-z0-9_]*/g,o=[],s;for(;(s=r.exec(e))!==null;)o.push({index:s.index,length:s[0].length,text:s[0],type:"url"});for(;(s=t.exec(e))!==null;){let a=s.index;o.some(c=>a>=c.index&&a<c.index+c.length)||o.push({index:a,length:s[0].length,text:s[0],type:"hashtag"});}for(;(s=n.exec(e))!==null;){let a=s.index;o.some(c=>a>=c.index&&a<c.index+c.length)||o.push({index:a,length:s[0].length,text:s[0],type:"symbol"});}o.sort((a,u)=>a.index-u.index);let i=[],d=0,p=0;return o.forEach(a=>{if(a.index>d&&i.push(e.slice(d,a.index)),a.type==="url"){let u=a.text.startsWith("http")?a.text:`https://${a.text}`;i.push(jsxRuntime.jsx("a",{href:u,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:c=>c.stopPropagation(),children:a.text},p++));}else if(a.type==="hashtag"){let c=`https://x.com/hashtag/${a.text.slice(1)}`;i.push(jsxRuntime.jsx("a",{href:c,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:T=>T.stopPropagation(),children:a.text},p++));}else a.type==="symbol"&&i.push(jsxRuntime.jsx("span",{className:"text-primary",children:a.text},p++));d=a.index+a.length;}),d<e.length&&i.push(e.slice(d)),i.length>0?i:[e]}function G({content:e,isExpanded:r=false,onLoad:t}){let n=react.useRef(null),o=react.useMemo(()=>q(e),[e]);return react.useEffect(()=>{let s=n.current;!t||!s||s.scrollHeight>s.clientHeight&&t?.();},[r]),jsxRuntime.jsx("div",{ref:n,className:["text-default-900 text-sm leading-5",r?"":"line-clamp-3"].join(" "),onClick:s=>{s.stopPropagation();},children:o})}function f({data:e,renderActions:r,embed:t=false,indicator:n,children:o}){let[s,i]=react.useState(void 0),d=react.useMemo(()=>t?"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",[t]),p=hooks.useTickAge(e.timestamp);return jsxRuntime.jsxs("div",{className:["flex flex-col gap-1.5 cursor-pointer",d].join(" "),onClick:()=>{window.open(utils.twitterTweetUrl(e.tweetId),"_blank");},children:[jsxRuntime.jsx($,{user:e.user,renderTimestamp:t?void 0:jsxRuntime.jsx("div",{className:"text-xs text-primary",children:utils.formatAge(p)})}),n,e.content.text&&jsxRuntime.jsx(G,{content:e.content.text,isExpanded:s,onLoad:()=>i(false)}),e.content.text&&jsxRuntime.jsx(D,{text:e.content.text,renderActions:jsxRuntime.jsx(Z,{isExpanded:s,onToggleExpand:i})}),jsxRuntime.jsx("div",{className:ui.clsx((!e.content.medias||e.content.medias.length===0)&&"hidden"),children:e.content.medias&&e.content.medias.length>0&&jsxRuntime.jsx(O,{medias:e.content.medias,tweetHref:utils.twitterTweetUrl(e.tweetId)})}),o,r]})}function K({data:e,renderActions:r}){return jsxRuntime.jsx(f,{data:e.tweet,renderActions:r})}function Y({data:e,renderActions:r}){let t=e.sourceTweet,n=!!t;return jsxRuntime.jsx(f,{data:e.tweet,renderActions:r,children:n?jsxRuntime.jsx(f,{data:t,embed:true}):null})}function ee({data:e,renderActions:r}){let t=e.sourceTweet,n=!!t,o=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(t.user.screenName??t.user.username),children:["@",t.user.screenName??t.user.username]})]}),[n,t]);return jsxRuntime.jsx(f,{data:e.tweet,indicator:o,renderActions:r,children:n?jsxRuntime.jsx(f,{data:t,embed:true}):null})}function re({data:e,renderActions:r}){let t=e.sourceTweet,n=!!t,o=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(t.user.screenName??t.user.username),children:["@",t.user.screenName??t.user.username]})]}),[n,t]);return jsxRuntime.jsx(f,{data:e.tweet,indicator:o,renderActions:r,children:n?jsxRuntime.jsx(f,{data:t,embed:true}):null})}function oe({data:e,renderActions:r,embed:t=false,children:n,loading:o=false}){if(o||!e)return jsxRuntime.jsx(Xe,{embed:t});let s=e.tweet.type;return jsxRuntime.jsx("div",{className:"w-full",children:(()=>{let d={data:e,renderActions:r,embed:t,children:n};switch(s){case "reply":return jsxRuntime.jsx(ee,{...d});case "retweet":return jsxRuntime.jsx(re,{...d});case "quote":return jsxRuntime.jsx(Y,{...d});default:return jsxRuntime.jsx(K,{...d})}})()})}function Xe({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 ae({token:e}){let r=new utils.SafeBigNumber(e.priceChange??"0").isPositive()?"primary":"danger";return jsxRuntime.jsxs(ui.Button,{color:r,variant:"flat",size:"sm",radius:"full",startContent:jsxRuntime.jsx(at,{token:e}),children:[jsxRuntime.jsx("span",{children:e.symbol}),jsxRuntime.jsxs("span",{children:[e.priceChange?utils.formatPercent(e.priceChange):"--","%"]})]})}function at({token:e}){let r=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:r,shape:"circle",placement:"bottom-right",children:jsxRuntime.jsx(ui.Avatar,{className:"w-5 h-5",radius:"full",src:e.image})})}function le({type:e}){let{t:r}=i18n.useTranslation();return e==="sell"?jsxRuntime.jsx(ui.Button,{size:"sm",variant:"flat",color:"danger",startContent:jsxRuntime.jsx(ui.LightningIcon,{}),children:r("common.sell")}):jsxRuntime.jsx(ui.Button,{size:"sm",variant:"flat",color:"primary",startContent:jsxRuntime.jsx(ui.LightningIcon,{}),children:r("common.buy")})}function de({data:e,loading:r,setIsPaused:t}){let n=o=>jsxRuntime.jsxs("div",{className:"flex gap-2.5 justify-between",children:[o.token&&jsxRuntime.jsx(ae,{token:o.token}),o.token&&jsxRuntime.jsx(le,{token:o.token})]});return jsxRuntime.jsx("div",{className:"flex flex-col gap-2.5",onMouseEnter:()=>t(true),onMouseLeave:()=>t(false),children:e.map(o=>jsxRuntime.jsx(oe,{data:o,renderActions:n(o),loading:r},o.id))})}function lt(){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 ce({count:e=3}){return jsxRuntime.jsx("div",{className:"flex flex-col gap-2",children:Array.from({length:e}).map((r,t)=>jsxRuntime.jsx(lt,{},t))})}var R=react.createContext({});function me(){let e=react.useContext(R);if(!e)throw new Error("useMediaTrackContext must be used within a MediaTrackProvider");return e}function pe(){let{client:e}=me();return e}var fe=()=>{let[e,r]=react.useState([]),[t,n]=react.useState(true),[o,s]=react.useState(false),i=pe(),d=react.useCallback(p=>{r(a=>{let u=a.findIndex(T=>T.id===p.id),c;if(u>=0)c=a.map((T,xe)=>xe===u?p:T);else {if(o)return a;c=[p,...a];}return c.slice(0,30)}),n(false);},[o]);return react.useEffect(()=>{let p=i.subscribeTweetMedia({callback:d}),a=i.subscribeTweetMediaToken({callback:d});return ()=>{p.unsubscribe(),a.unsubscribe();}},[i,d]),{medias:e,loading:t,isPaused:o,setIsPaused:s}};function Oo(){let{medias:e,loading:r,isPaused:t,setIsPaused:n}=fe();return r?jsxRuntime.jsx(ce,{count:3}):jsxRuntime.jsx(de,{data:e,loading:r,setIsPaused:n})}function Xo({client:e,children:r}){return jsxRuntime.jsx(R.Provider,{value:{client:e},children:r})}
|
|
2
|
+
exports.MediaImage=U;exports.MediaTrackContext=R;exports.MediaTrackProvider=Xo;exports.MediaVideo=F;exports.Medias=O;exports.TextExpand=Z;exports.Translate=D;exports.TweetItem=oe;exports.TweetOriginal=K;exports.TweetQuote=Y;exports.TweetReply=ee;exports.TweetRetweet=re;exports.TweetSkeleton=lt;exports.TweetSkeletonList=ce;exports.TweetSource=f;exports.Tweets=de;exports.TweetsWidget=Oo;exports.UserAvatar=H;exports.UserInfo=$;exports.useMediaTrackClient=pe;exports.useMediaTrackContext=me;exports.useTweets=fe;exports.version=we;//# sourceMappingURL=index.js.map
|
|
3
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/version.ts","../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/components/tweets/tweet/tools/translate.tsx","../src/components/tweets/tweet/tools/text-expand.tsx","../src/utils/parseText.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/tweet/tools/tweet-trade-button.tsx","../src/components/tweets/tweets.ui.tsx","../src/components/tweets/tweet/tweet-skeleton.tsx","../src/context/MediaTrackContext.ts","../src/hooks/useMediaTrackContext.ts","../src/hooks/useMediaTrackClient.ts","../src/components/tweets/tweets.script.ts","../src/components/tweets/tweets.widget.tsx","../src/providers/MediaTrackProvider.tsx"],"names":["version_default","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","Translate","text","isTranslate","toggle","t","useTranslation","renderTranslateText","Fragment","ev","TranslateIcon","clsx","e","TextExpand","isExpanded","onToggleExpand","renderExpand","ChevronUpIcon","ChevronDownIcon","parseText","urlRegex","hashtagRegex","symbolRegex","matches","match","matchIndex","m","b","parts","lastIndex","key","item","hashtagUrl","Content","content","onLoad","ref","useRef","parsedContent","useEffect","current","TweetSource","data","embed","indicator","children","setIsExpanded","useState","containerClass","age","useTickAge","twitterTweetUrl","formatAge","TweetOriginal","TweetQuote","sourceTweet","hasSource","TweetReply","TweetRetweet","TweetItem","loading","TweetSkeleton","tweetType","commonProps","TweetTokenButton","token","color","SafeBigNumber","Button","TweetTokenIcon","formatPercent","ChainIcon","Image","Badge","TweetTradeButton","type","LightningIcon","Tweets","setIsPaused","TweetSkeletonList","count","_","index","MediaTrackContext","createContext","useMediaTrackContext","context","useContext","useMediaTrackClient","client","useTweets","setMedias","setLoading","isPaused","handleMedia","useCallback","prevMedias","idx","it","newMedias","subTweet","subTweetToken","TweetsWidget","MediaTrackProvider"],"mappings":"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","file":"index.js","sourcesContent":["declare global {\n interface Window {\n __LIBERFI_VERSION__?: {\n [key: string]: string;\n };\n }\n}\nif (typeof window !== \"undefined\") {\n window.__LIBERFI_VERSION__ = window.__LIBERFI_VERSION__ || {};\n window.__LIBERFI_VERSION__[\"@liberfi.io/ui-media-track\"] = \"0.1.4\";\n}\n\nexport default \"0.1.4\";\n","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 { TweetContentMedia } from \"@liberfi.io/types\";\nimport { Link } from \"@liberfi.io/ui\";\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 { TweetUser } from \"@liberfi.io/types\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\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 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 {renderActions}\n </div>\n );\n}\n","import React from \"react\";\nimport { useBoolean } from \"@liberfi.io/hooks\";\nimport { useTranslation } from \"@liberfi.io/i18n\";\nimport { clsx, TranslateIcon } from \"@liberfi.io/ui\";\n\ntype Props = {\n text: string;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function Translate({ text, renderActions }: Props) {\n const [isTranslate, { toggle }] = useBoolean(false);\n const { t } = useTranslation();\n const renderTranslateText = () => {\n if (!isTranslate) return null;\n // TODO: render translated text\n return (\n <div className=\"bg-content2 rounded-md p-2 text-default-900 text-sm leading-5\">\n {text}\n </div>\n );\n };\n\n return (\n <>\n <div className=\"flex items-center gap-1 text-xs\">\n <div\n onClick={(ev) => {\n ev.stopPropagation();\n toggle();\n }}\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={clsx(!isTranslate && \"hidden\")}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n {renderTranslateText()}\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","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, { 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 { SourceTweet, Tweet } from \"@liberfi.io/types\";\nimport { clsx } from \"@liberfi.io/ui\";\nimport { formatAge, twitterTweetUrl } from \"@liberfi.io/utils\";\nimport { Content } from \"./content\";\nimport { Medias } from \"./media\";\nimport { Translate, TextExpand } from \"./tools\";\nimport { UserInfo } from \"./user\";\n\ntype Props = {\n data: Tweet | SourceTweet;\n renderActions?: React.ReactNode;\n embed?: boolean;\n indicator?: React.ReactNode;\n children?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetSource({\n data,\n renderActions,\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 age = useTickAge((data as Tweet).timestamp);\n\n return (\n <div\n className={[\"flex flex-col gap-1.5 cursor-pointer\", containerClass].join(\n \" \",\n )}\n onClick={() => {\n window.open(twitterTweetUrl(data.tweetId), \"_blank\");\n }}\n >\n {/* -------- USER INFO -------- */}\n <UserInfo\n user={data.user}\n renderTimestamp={\n embed ? undefined : (\n <div className=\"text-xs text-primary\">{formatAge(age)}</div>\n )\n }\n />\n\n {/* -------- MESSAGE TYPE INDICATOR -------- */}\n {indicator}\n\n {/* -------- CONTENT -------- */}\n {data.content.text && (\n <Content\n content={data.content.text}\n isExpanded={isExpanded}\n onLoad={() => setIsExpanded(false)}\n />\n )}\n\n {/* -------- TOOLS -------- */}\n {data.content.text && (\n <Translate\n text={data.content.text}\n renderActions={\n <TextExpand\n isExpanded={isExpanded}\n onToggleExpand={setIsExpanded}\n />\n }\n />\n )}\n\n {/* -------- MEDIA -------- */}\n <div\n className={clsx(\n (!data.content.medias || data.content.medias.length === 0) &&\n \"hidden\",\n )}\n >\n {data.content.medias && data.content.medias.length > 0 && (\n <Medias\n medias={data.content.medias}\n tweetHref={twitterTweetUrl(data.tweetId)}\n />\n )}\n </div>\n\n {/* -------- CHILDREN -------- */}\n {children}\n\n {/* -------- Custom ACTIONS -------- */}\n {renderActions}\n </div>\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"@liberfi.io/types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetOriginal({ data, renderActions }: Props) {\n return <TweetSource data={data.tweet} renderActions={renderActions} />;\n}\n","import React from \"react\";\nimport { TweetMedia } from \"@liberfi.io/types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetQuote({ data, renderActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n return (\n <TweetSource data={data.tweet} renderActions={renderActions}>\n {hasSource ? <TweetSource data={sourceTweet} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { TweetMedia } from \"@liberfi.io/types\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetReply({ data, renderActions }: 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.tweet}\n indicator={indicator}\n renderActions={renderActions}\n >\n {hasSource ? <TweetSource data={sourceTweet} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { TweetMedia } from \"@liberfi.io/types\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetRetweet({ data, renderActions }: 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.tweet}\n indicator={indicator}\n renderActions={renderActions}\n >\n {hasSource ? <TweetSource data={sourceTweet} embed /> : null}\n </TweetSource>\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"@liberfi.io/types\";\nimport { Skeleton } from \"@liberfi.io/ui\";\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 renderActions?: React.ReactNode;\n embed?: boolean;\n children?: React.ReactNode;\n loading?: boolean;\n};\n\n// ------------------------------------------------------------\nexport function TweetItem({\n data,\n renderActions,\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 renderActions,\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 ? formatPercent(token.priceChange) : \"--\"}%\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 { useTranslation } from \"@liberfi.io/i18n\";\nimport { Button, LightningIcon } from \"@liberfi.io/ui\";\nimport { MediaToken } from \"../../../../types\";\n\ntype Props = {\n token: MediaToken;\n type?: \"buy\" | \"sell\";\n};\n\nexport function TweetTradeButton({ type }: Props) {\n const { t } = useTranslation();\n if (type === \"sell\") {\n return (\n <Button\n size=\"sm\"\n variant=\"flat\"\n color=\"danger\"\n startContent={<LightningIcon />}\n >\n {t(\"common.sell\")}\n </Button>\n );\n }\n\n return (\n <Button\n size=\"sm\"\n variant=\"flat\"\n color=\"primary\"\n startContent={<LightningIcon />}\n >\n {t(\"common.buy\")}\n </Button>\n );\n}\n","import { TweetMedia } from \"@liberfi.io/types\";\nimport { TweetTokenButton } from \"./tweet/tools/tweet-token-button\";\nimport { 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};\n\n// ------------------------------------------------------------\nexport function Tweets({ data, loading, setIsPaused }: TweetsProps) {\n const renderActions = (item: TweetMedia) => (\n <div className=\"flex gap-2.5 justify-between\">\n {item.token && <TweetTokenButton token={item.token} />}\n {item.token && <TweetTradeButton token={item.token} />}\n </div>\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 renderActions={renderActions(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 { createContext } from \"react\";\nimport { API } from \"@liberfi.io/types\";\n\nexport interface MediaTrackContextValue {\n client: API.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 { useCallback, useEffect, useState } from \"react\";\nimport { TweetMedia } from \"@liberfi.io/types\";\nimport { useMediaTrackClient } from \"../../hooks\";\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 { TweetSkeletonList } from \"./tweet/tweet-skeleton\";\nimport { useTweets } from \"./tweets.script\";\nimport { Tweets } from \"./tweets.ui\";\n\n// ------------------------------------------------------------\nexport function TweetsWidget() {\n const { medias, loading, isPaused, setIsPaused } = useTweets();\n\n if (loading) {\n return <TweetSkeletonList count={3} />;\n }\n\n return <Tweets data={medias} loading={loading} setIsPaused={setIsPaused} />;\n}\n","import { PropsWithChildren } from \"react\";\nimport { API } from \"@liberfi.io/types\";\nimport { MediaTrackContext } from \"../context\";\n\nexport type MediaTrackProviderProps = PropsWithChildren<{\n client: API.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"]}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
import {useBoolean,useTickAge}from'@liberfi.io/hooks';import {Skeleton,Avatar,Link,TranslateIcon,clsx,ChevronUpIcon,ChevronDownIcon,Button,LightningIcon,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,useState,useContext,useCallback,useEffect,useRef}from'react';import {useTranslation}from'@liberfi.io/i18n';typeof window<"u"&&(window.__LIBERFI_VERSION__=window.__LIBERFI_VERSION__||{},window.__LIBERFI_VERSION__["@liberfi.io/ui-media-track"]="0.1.4");var we="0.1.4";function U({src:e}){let[r,{setTrue:t}]=useBoolean(false);return e?jsx(Skeleton,{isLoaded:r,className:"w-full h-auto",children:jsx("img",{src:e,className:"w-full h-full object-cover aspect-video",onLoad:()=>{t();}})}):null}function F({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 O({medias:e,tweetHref:r}){let t=e.filter(i=>i.type==="image"),n=e.filter(i=>i.type==="video"),o=()=>n.length?jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:n.map(i=>jsx(F,{src:i.url},i.url))}):null,s=()=>t.length?jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:t.map(i=>jsx(Link,{href:r,target:"_blank",children:jsx(U,{src:i.url})},i.url))}):null;return jsxs("div",{className:"flex flex-col gap-2",children:[o(),s()]})}function H({url:e,name:r="",size:t=36}){let n=useMemo(()=>r?r.slice(0,2):"N/A",[r]);return jsx(Skeleton,{className:"flex rounded-full flex-shrink-0",style:{width:t,height:t},isLoaded:!!e,children:jsx(Avatar,{size:"md",color:"primary",radius:"full",showFallback:true,name:n,src:e,style:{width:t,height:t}})})}function $({user:e,renderTimestamp:r,renderActions:t}){return jsxs("div",{className:"flex items-center gap-1",children:[jsx(H,{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}),r]}),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]})]}),t]})}function D({text:e,renderActions:r}){let[t,{toggle:n}]=useBoolean(false),{t:o}=useTranslation(),s=()=>t?jsx("div",{className:"bg-content2 rounded-md p-2 text-default-900 text-sm leading-5",children:e}):null;return jsxs(Fragment,{children:[jsxs("div",{className:"flex items-center gap-1 text-xs",children:[jsxs("div",{onClick:i=>{i.stopPropagation(),n();},className:"flex items-center gap-0.5 cursor-pointer text-primary hover:text-foreground",children:[jsx(TranslateIcon,{width:"14",height:"14"}),o(t?"mediaTrack.tweets.translate.hide":"mediaTrack.tweets.translate.show")]}),r]}),jsx("div",{className:clsx(!t&&"hidden"),onClick:i=>{i.stopPropagation();},children:s()})]})}function Z({isExpanded:e,onToggleExpand:r}){let{t}=useTranslation(),n=()=>e?jsxs(Fragment,{children:[jsx(ChevronUpIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",t("mediaTrack.tweets.collapse")]}):jsxs(Fragment,{children:[jsx(ChevronDownIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",t("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:o=>{o.stopPropagation(),r?.(!e);},className:"flex items-center text-default-500 hover:text-foreground text-xs",children:n()})]})}function q(e){let r=/(https?:\/\/[^\s]+|www\.[^\s]+)/gi,t=/#[\w]+/g,n=/\$[A-Za-z][A-Za-z0-9_]*/g,o=[],s;for(;(s=r.exec(e))!==null;)o.push({index:s.index,length:s[0].length,text:s[0],type:"url"});for(;(s=t.exec(e))!==null;){let a=s.index;o.some(c=>a>=c.index&&a<c.index+c.length)||o.push({index:a,length:s[0].length,text:s[0],type:"hashtag"});}for(;(s=n.exec(e))!==null;){let a=s.index;o.some(c=>a>=c.index&&a<c.index+c.length)||o.push({index:a,length:s[0].length,text:s[0],type:"symbol"});}o.sort((a,u)=>a.index-u.index);let i=[],d=0,p=0;return o.forEach(a=>{if(a.index>d&&i.push(e.slice(d,a.index)),a.type==="url"){let u=a.text.startsWith("http")?a.text:`https://${a.text}`;i.push(jsx("a",{href:u,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:c=>c.stopPropagation(),children:a.text},p++));}else if(a.type==="hashtag"){let c=`https://x.com/hashtag/${a.text.slice(1)}`;i.push(jsx("a",{href:c,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:T=>T.stopPropagation(),children:a.text},p++));}else a.type==="symbol"&&i.push(jsx("span",{className:"text-primary",children:a.text},p++));d=a.index+a.length;}),d<e.length&&i.push(e.slice(d)),i.length>0?i:[e]}function G({content:e,isExpanded:r=false,onLoad:t}){let n=useRef(null),o=useMemo(()=>q(e),[e]);return useEffect(()=>{let s=n.current;!t||!s||s.scrollHeight>s.clientHeight&&t?.();},[r]),jsx("div",{ref:n,className:["text-default-900 text-sm leading-5",r?"":"line-clamp-3"].join(" "),onClick:s=>{s.stopPropagation();},children:o})}function f({data:e,renderActions:r,embed:t=false,indicator:n,children:o}){let[s,i]=useState(void 0),d=useMemo(()=>t?"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",[t]),p=useTickAge(e.timestamp);return jsxs("div",{className:["flex flex-col gap-1.5 cursor-pointer",d].join(" "),onClick:()=>{window.open(twitterTweetUrl(e.tweetId),"_blank");},children:[jsx($,{user:e.user,renderTimestamp:t?void 0:jsx("div",{className:"text-xs text-primary",children:formatAge(p)})}),n,e.content.text&&jsx(G,{content:e.content.text,isExpanded:s,onLoad:()=>i(false)}),e.content.text&&jsx(D,{text:e.content.text,renderActions:jsx(Z,{isExpanded:s,onToggleExpand:i})}),jsx("div",{className:clsx((!e.content.medias||e.content.medias.length===0)&&"hidden"),children:e.content.medias&&e.content.medias.length>0&&jsx(O,{medias:e.content.medias,tweetHref:twitterTweetUrl(e.tweetId)})}),o,r]})}function K({data:e,renderActions:r}){return jsx(f,{data:e.tweet,renderActions:r})}function Y({data:e,renderActions:r}){let t=e.sourceTweet,n=!!t;return jsx(f,{data:e.tweet,renderActions:r,children:n?jsx(f,{data:t,embed:true}):null})}function ee({data:e,renderActions:r}){let t=e.sourceTweet,n=!!t,o=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(t.user.screenName??t.user.username),children:["@",t.user.screenName??t.user.username]})]}),[n,t]);return jsx(f,{data:e.tweet,indicator:o,renderActions:r,children:n?jsx(f,{data:t,embed:true}):null})}function re({data:e,renderActions:r}){let t=e.sourceTweet,n=!!t,o=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(t.user.screenName??t.user.username),children:["@",t.user.screenName??t.user.username]})]}),[n,t]);return jsx(f,{data:e.tweet,indicator:o,renderActions:r,children:n?jsx(f,{data:t,embed:true}):null})}function oe({data:e,renderActions:r,embed:t=false,children:n,loading:o=false}){if(o||!e)return jsx(Xe,{embed:t});let s=e.tweet.type;return jsx("div",{className:"w-full",children:(()=>{let d={data:e,renderActions:r,embed:t,children:n};switch(s){case "reply":return jsx(ee,{...d});case "retweet":return jsx(re,{...d});case "quote":return jsx(Y,{...d});default:return jsx(K,{...d})}})()})}function Xe({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 ae({token:e}){let r=new SafeBigNumber(e.priceChange??"0").isPositive()?"primary":"danger";return jsxs(Button,{color:r,variant:"flat",size:"sm",radius:"full",startContent:jsx(at,{token:e}),children:[jsx("span",{children:e.symbol}),jsxs("span",{children:[e.priceChange?formatPercent(e.priceChange):"--","%"]})]})}function at({token:e}){let r=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:r,shape:"circle",placement:"bottom-right",children:jsx(Avatar,{className:"w-5 h-5",radius:"full",src:e.image})})}function le({type:e}){let{t:r}=useTranslation();return e==="sell"?jsx(Button,{size:"sm",variant:"flat",color:"danger",startContent:jsx(LightningIcon,{}),children:r("common.sell")}):jsx(Button,{size:"sm",variant:"flat",color:"primary",startContent:jsx(LightningIcon,{}),children:r("common.buy")})}function de({data:e,loading:r,setIsPaused:t}){let n=o=>jsxs("div",{className:"flex gap-2.5 justify-between",children:[o.token&&jsx(ae,{token:o.token}),o.token&&jsx(le,{token:o.token})]});return jsx("div",{className:"flex flex-col gap-2.5",onMouseEnter:()=>t(true),onMouseLeave:()=>t(false),children:e.map(o=>jsx(oe,{data:o,renderActions:n(o),loading:r},o.id))})}function lt(){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 ce({count:e=3}){return jsx("div",{className:"flex flex-col gap-2",children:Array.from({length:e}).map((r,t)=>jsx(lt,{},t))})}var R=createContext({});function me(){let e=useContext(R);if(!e)throw new Error("useMediaTrackContext must be used within a MediaTrackProvider");return e}function pe(){let{client:e}=me();return e}var fe=()=>{let[e,r]=useState([]),[t,n]=useState(true),[o,s]=useState(false),i=pe(),d=useCallback(p=>{r(a=>{let u=a.findIndex(T=>T.id===p.id),c;if(u>=0)c=a.map((T,xe)=>xe===u?p:T);else {if(o)return a;c=[p,...a];}return c.slice(0,30)}),n(false);},[o]);return useEffect(()=>{let p=i.subscribeTweetMedia({callback:d}),a=i.subscribeTweetMediaToken({callback:d});return ()=>{p.unsubscribe(),a.unsubscribe();}},[i,d]),{medias:e,loading:t,isPaused:o,setIsPaused:s}};function Oo(){let{medias:e,loading:r,isPaused:t,setIsPaused:n}=fe();return r?jsx(ce,{count:3}):jsx(de,{data:e,loading:r,setIsPaused:n})}function Xo({client:e,children:r}){return jsx(R.Provider,{value:{client:e},children:r})}
|
|
2
|
+
export{U as MediaImage,R as MediaTrackContext,Xo as MediaTrackProvider,F as MediaVideo,O as Medias,Z as TextExpand,D as Translate,oe as TweetItem,K as TweetOriginal,Y as TweetQuote,ee as TweetReply,re as TweetRetweet,lt as TweetSkeleton,ce as TweetSkeletonList,f as TweetSource,de as Tweets,Oo as TweetsWidget,H as UserAvatar,$ as UserInfo,pe as useMediaTrackClient,me as useMediaTrackContext,fe as useTweets,we as version};//# sourceMappingURL=index.mjs.map
|
|
3
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/version.ts","../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/components/tweets/tweet/tools/translate.tsx","../src/components/tweets/tweet/tools/text-expand.tsx","../src/utils/parseText.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/tweet/tools/tweet-trade-button.tsx","../src/components/tweets/tweets.ui.tsx","../src/components/tweets/tweet/tweet-skeleton.tsx","../src/context/MediaTrackContext.ts","../src/hooks/useMediaTrackContext.ts","../src/hooks/useMediaTrackClient.ts","../src/components/tweets/tweets.script.ts","../src/components/tweets/tweets.widget.tsx","../src/providers/MediaTrackProvider.tsx"],"names":["version_default","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","Translate","text","isTranslate","toggle","t","useTranslation","renderTranslateText","Fragment","ev","TranslateIcon","clsx","e","TextExpand","isExpanded","onToggleExpand","renderExpand","ChevronUpIcon","ChevronDownIcon","parseText","urlRegex","hashtagRegex","symbolRegex","matches","match","matchIndex","m","b","parts","lastIndex","key","item","hashtagUrl","Content","content","onLoad","ref","useRef","parsedContent","useEffect","current","TweetSource","data","embed","indicator","children","setIsExpanded","useState","containerClass","age","useTickAge","twitterTweetUrl","formatAge","TweetOriginal","TweetQuote","sourceTweet","hasSource","TweetReply","TweetRetweet","TweetItem","loading","TweetSkeleton","tweetType","commonProps","TweetTokenButton","token","color","SafeBigNumber","Button","TweetTokenIcon","formatPercent","ChainIcon","Image","Badge","TweetTradeButton","type","LightningIcon","Tweets","setIsPaused","TweetSkeletonList","count","_","index","MediaTrackContext","createContext","useMediaTrackContext","context","useContext","useMediaTrackClient","client","useTweets","setMedias","setLoading","isPaused","handleMedia","useCallback","prevMedias","idx","it","newMedias","subTweet","subTweetToken","TweetsWidget","MediaTrackProvider"],"mappings":"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","file":"index.mjs","sourcesContent":["declare global {\n interface Window {\n __LIBERFI_VERSION__?: {\n [key: string]: string;\n };\n }\n}\nif (typeof window !== \"undefined\") {\n window.__LIBERFI_VERSION__ = window.__LIBERFI_VERSION__ || {};\n window.__LIBERFI_VERSION__[\"@liberfi.io/ui-media-track\"] = \"0.1.4\";\n}\n\nexport default \"0.1.4\";\n","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 { TweetContentMedia } from \"@liberfi.io/types\";\nimport { Link } from \"@liberfi.io/ui\";\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 { TweetUser } from \"@liberfi.io/types\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\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 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 {renderActions}\n </div>\n );\n}\n","import React from \"react\";\nimport { useBoolean } from \"@liberfi.io/hooks\";\nimport { useTranslation } from \"@liberfi.io/i18n\";\nimport { clsx, TranslateIcon } from \"@liberfi.io/ui\";\n\ntype Props = {\n text: string;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function Translate({ text, renderActions }: Props) {\n const [isTranslate, { toggle }] = useBoolean(false);\n const { t } = useTranslation();\n const renderTranslateText = () => {\n if (!isTranslate) return null;\n // TODO: render translated text\n return (\n <div className=\"bg-content2 rounded-md p-2 text-default-900 text-sm leading-5\">\n {text}\n </div>\n );\n };\n\n return (\n <>\n <div className=\"flex items-center gap-1 text-xs\">\n <div\n onClick={(ev) => {\n ev.stopPropagation();\n toggle();\n }}\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={clsx(!isTranslate && \"hidden\")}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n {renderTranslateText()}\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","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, { 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 { SourceTweet, Tweet } from \"@liberfi.io/types\";\nimport { clsx } from \"@liberfi.io/ui\";\nimport { formatAge, twitterTweetUrl } from \"@liberfi.io/utils\";\nimport { Content } from \"./content\";\nimport { Medias } from \"./media\";\nimport { Translate, TextExpand } from \"./tools\";\nimport { UserInfo } from \"./user\";\n\ntype Props = {\n data: Tweet | SourceTweet;\n renderActions?: React.ReactNode;\n embed?: boolean;\n indicator?: React.ReactNode;\n children?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetSource({\n data,\n renderActions,\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 age = useTickAge((data as Tweet).timestamp);\n\n return (\n <div\n className={[\"flex flex-col gap-1.5 cursor-pointer\", containerClass].join(\n \" \",\n )}\n onClick={() => {\n window.open(twitterTweetUrl(data.tweetId), \"_blank\");\n }}\n >\n {/* -------- USER INFO -------- */}\n <UserInfo\n user={data.user}\n renderTimestamp={\n embed ? undefined : (\n <div className=\"text-xs text-primary\">{formatAge(age)}</div>\n )\n }\n />\n\n {/* -------- MESSAGE TYPE INDICATOR -------- */}\n {indicator}\n\n {/* -------- CONTENT -------- */}\n {data.content.text && (\n <Content\n content={data.content.text}\n isExpanded={isExpanded}\n onLoad={() => setIsExpanded(false)}\n />\n )}\n\n {/* -------- TOOLS -------- */}\n {data.content.text && (\n <Translate\n text={data.content.text}\n renderActions={\n <TextExpand\n isExpanded={isExpanded}\n onToggleExpand={setIsExpanded}\n />\n }\n />\n )}\n\n {/* -------- MEDIA -------- */}\n <div\n className={clsx(\n (!data.content.medias || data.content.medias.length === 0) &&\n \"hidden\",\n )}\n >\n {data.content.medias && data.content.medias.length > 0 && (\n <Medias\n medias={data.content.medias}\n tweetHref={twitterTweetUrl(data.tweetId)}\n />\n )}\n </div>\n\n {/* -------- CHILDREN -------- */}\n {children}\n\n {/* -------- Custom ACTIONS -------- */}\n {renderActions}\n </div>\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"@liberfi.io/types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetOriginal({ data, renderActions }: Props) {\n return <TweetSource data={data.tweet} renderActions={renderActions} />;\n}\n","import React from \"react\";\nimport { TweetMedia } from \"@liberfi.io/types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetQuote({ data, renderActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n return (\n <TweetSource data={data.tweet} renderActions={renderActions}>\n {hasSource ? <TweetSource data={sourceTweet} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { TweetMedia } from \"@liberfi.io/types\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetReply({ data, renderActions }: 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.tweet}\n indicator={indicator}\n renderActions={renderActions}\n >\n {hasSource ? <TweetSource data={sourceTweet} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { TweetMedia } from \"@liberfi.io/types\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetRetweet({ data, renderActions }: 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.tweet}\n indicator={indicator}\n renderActions={renderActions}\n >\n {hasSource ? <TweetSource data={sourceTweet} embed /> : null}\n </TweetSource>\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"@liberfi.io/types\";\nimport { Skeleton } from \"@liberfi.io/ui\";\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 renderActions?: React.ReactNode;\n embed?: boolean;\n children?: React.ReactNode;\n loading?: boolean;\n};\n\n// ------------------------------------------------------------\nexport function TweetItem({\n data,\n renderActions,\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 renderActions,\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 ? formatPercent(token.priceChange) : \"--\"}%\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 { useTranslation } from \"@liberfi.io/i18n\";\nimport { Button, LightningIcon } from \"@liberfi.io/ui\";\nimport { MediaToken } from \"../../../../types\";\n\ntype Props = {\n token: MediaToken;\n type?: \"buy\" | \"sell\";\n};\n\nexport function TweetTradeButton({ type }: Props) {\n const { t } = useTranslation();\n if (type === \"sell\") {\n return (\n <Button\n size=\"sm\"\n variant=\"flat\"\n color=\"danger\"\n startContent={<LightningIcon />}\n >\n {t(\"common.sell\")}\n </Button>\n );\n }\n\n return (\n <Button\n size=\"sm\"\n variant=\"flat\"\n color=\"primary\"\n startContent={<LightningIcon />}\n >\n {t(\"common.buy\")}\n </Button>\n );\n}\n","import { TweetMedia } from \"@liberfi.io/types\";\nimport { TweetTokenButton } from \"./tweet/tools/tweet-token-button\";\nimport { 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};\n\n// ------------------------------------------------------------\nexport function Tweets({ data, loading, setIsPaused }: TweetsProps) {\n const renderActions = (item: TweetMedia) => (\n <div className=\"flex gap-2.5 justify-between\">\n {item.token && <TweetTokenButton token={item.token} />}\n {item.token && <TweetTradeButton token={item.token} />}\n </div>\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 renderActions={renderActions(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 { createContext } from \"react\";\nimport { API } from \"@liberfi.io/types\";\n\nexport interface MediaTrackContextValue {\n client: API.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 { useCallback, useEffect, useState } from \"react\";\nimport { TweetMedia } from \"@liberfi.io/types\";\nimport { useMediaTrackClient } from \"../../hooks\";\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 { TweetSkeletonList } from \"./tweet/tweet-skeleton\";\nimport { useTweets } from \"./tweets.script\";\nimport { Tweets } from \"./tweets.ui\";\n\n// ------------------------------------------------------------\nexport function TweetsWidget() {\n const { medias, loading, isPaused, setIsPaused } = useTweets();\n\n if (loading) {\n return <TweetSkeletonList count={3} />;\n }\n\n return <Tweets data={medias} loading={loading} setIsPaused={setIsPaused} />;\n}\n","import { PropsWithChildren } from \"react\";\nimport { API } from \"@liberfi.io/types\";\nimport { MediaTrackContext } from \"../context\";\n\nexport type MediaTrackProviderProps = PropsWithChildren<{\n client: API.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"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@liberfi.io/ui-media-track",
|
|
3
|
+
"version": "0.1.5",
|
|
4
|
+
"description": "Media Track for Liberfi React SDK",
|
|
5
|
+
"main": "dist/index.js",
|
|
6
|
+
"module": "dist/index.mjs",
|
|
7
|
+
"types": "dist/index.d.ts",
|
|
8
|
+
"exports": {
|
|
9
|
+
".": {
|
|
10
|
+
"types": "./dist/index.d.ts",
|
|
11
|
+
"import": "./dist/index.mjs",
|
|
12
|
+
"require": "./dist/index.js"
|
|
13
|
+
},
|
|
14
|
+
"./client": {
|
|
15
|
+
"types": "./dist/client/index.d.ts",
|
|
16
|
+
"import": "./dist/client/index.mjs",
|
|
17
|
+
"require": "./dist/client/index.js"
|
|
18
|
+
}
|
|
19
|
+
},
|
|
20
|
+
"keywords": [],
|
|
21
|
+
"author": "liberfi.io",
|
|
22
|
+
"files": [
|
|
23
|
+
"dist"
|
|
24
|
+
],
|
|
25
|
+
"publishConfig": {
|
|
26
|
+
"access": "public"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@chainstream-io/centrifuge": "^1.0.0",
|
|
30
|
+
"@tanstack/react-query": "^5.90.2",
|
|
31
|
+
"react": "^19.1.1",
|
|
32
|
+
"react-dom": "^19.1.1",
|
|
33
|
+
"tailwind-variants": "^3.1.1",
|
|
34
|
+
"@liberfi.io/core": "0.1.5",
|
|
35
|
+
"@liberfi.io/hooks": "0.1.5",
|
|
36
|
+
"@liberfi.io/utils": "0.1.5",
|
|
37
|
+
"@liberfi.io/types": "0.1.5",
|
|
38
|
+
"@liberfi.io/i18n": "0.1.5",
|
|
39
|
+
"@liberfi.io/ui": "0.1.7"
|
|
40
|
+
},
|
|
41
|
+
"devDependencies": {
|
|
42
|
+
"@tailwindcss/cli": "^4.1.13",
|
|
43
|
+
"@tailwindcss/postcss": "^4.1.13",
|
|
44
|
+
"@types/node": "^24.5.0",
|
|
45
|
+
"@types/react": "^19.1.13",
|
|
46
|
+
"@types/react-dom": "^19.1.9",
|
|
47
|
+
"autoprefixer": "^10.4.21",
|
|
48
|
+
"postcss": "^8.5.6",
|
|
49
|
+
"tailwindcss": "^4.1.13",
|
|
50
|
+
"tsup": "^8.5.0",
|
|
51
|
+
"typescript": "^5.9.2",
|
|
52
|
+
"tsconfig": "0.1.4"
|
|
53
|
+
},
|
|
54
|
+
"peerDependencies": {
|
|
55
|
+
"react": ">=18",
|
|
56
|
+
"react-dom": ">=18"
|
|
57
|
+
},
|
|
58
|
+
"scripts": {
|
|
59
|
+
"build": "tsup",
|
|
60
|
+
"build:css": "pnpm dlx @tailwindcss/cli -i ./src/tailwind/tailwind.css -o ./dist/styles.css",
|
|
61
|
+
"test": "echo \"Error: no test specified\" && exit 1"
|
|
62
|
+
}
|
|
63
|
+
}
|