@liberfi.io/ui-media-track 0.1.270 → 0.1.271
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/index.js +2 -2
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +2 -2
- package/dist/index.mjs.map +1 -1
- package/package.json +7 -7
package/dist/index.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
'use strict';var hooks=require('@liberfi.io/hooks'),ui=require('@liberfi.io/ui'),jsxRuntime=require('react/jsx-runtime'),utils=require('@liberfi.io/utils'),react=require('react'),i18n=require('@liberfi.io/i18n'),reactQuery=require('@tanstack/react-query');function S({src:e}){let[t,{setTrue:r}]=hooks.useBoolean(false);return e?jsxRuntime.jsx(ui.Skeleton,{isLoaded:t,className:"w-full h-auto",children:jsxRuntime.jsx("img",{src:e,className:"w-full h-full object-cover aspect-video",onLoad:()=>{r();}})}):null}function E({src:e}){return e?jsxRuntime.jsx("div",{className:"w-full h-full overflow-hidden rounded-md mt-2",children:jsxRuntime.jsx("iframe",{className:"w-full h-full aspect-video",src:e,allowFullScreen:true})}):null}function L({medias:e,tweetHref:t}){let r=e.filter(i=>i.type==="image"),o=e.filter(i=>i.type==="video"),a=()=>o.length?jsxRuntime.jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:o.map(i=>jsxRuntime.jsx(E,{src:i.url},i.url))}):null,s=()=>r.length?jsxRuntime.jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:r.map(i=>jsxRuntime.jsx(ui.Link,{href:t,target:"_blank",children:jsxRuntime.jsx(S,{src:i.url})},i.url))}):null;return jsxRuntime.jsxs("div",{className:"flex flex-col gap-2",children:[a(),s()]})}function U({url:e,name:t="",size:r=36}){let o=react.useMemo(()=>t?t.slice(0,2):"N/A",[t]);return jsxRuntime.jsx(ui.Skeleton,{className:"flex rounded-full flex-shrink-0",style:{width:r,height:r},isLoaded:!!e,children:jsxRuntime.jsx(ui.Avatar,{size:"md",color:"primary",radius:"full",showFallback:true,name:o,src:e,style:{width:r,height:r}})})}function B({user:e,renderTimestamp:t,renderActions:r}){return jsxRuntime.jsxs("div",{className:"flex items-center justify-between gap-1",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-1",children:[jsxRuntime.jsx(U,{url:e.avatar,name:e.username}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxRuntime.jsxs("div",{className:"flex flex-row items-baseline gap-1",children:[jsxRuntime.jsx("span",{className:"text-foreground font-semibold truncate leading-none",children:e.username}),t]}),jsxRuntime.jsxs(ui.Link,{target:"_blank",underline:"hover",className:"text-default-500 text-sm leading-none",href:utils.twitterUserUrl(e.screenName??e.username),children:["@",e.screenName??e.username]})]})]}),r]})}var N=react.createContext({});var h=react.createContext(null);function O(){let e=react.useContext(N);if(!e)throw new Error("useMediaTrackContext must be used within a MediaTrackProvider");return e}function y(){let{client:e}=O();return e}function Ue(e={}){let t=y();return reactQuery.useMutation({mutationFn:async r=>t.generateMeme(r),...e})}function H(){let e=react.useContext(h);if(!e)throw new Error("useMediaTrackRuntime must be used within a MediaTrackProvider");return e}async function se(e,{media:t,targetLanguage:r,options:o}){return await e.translate(t,r,o)}function _(e={}){let t=y();return reactQuery.useMutation({mutationFn:async r=>se(t,r),...e})}function R(e){let t=/(https?:\/\/[^\s]+|www\.[^\s]+)/gi,r=/#[\w]+/g,o=/\$[A-Za-z][A-Za-z0-9_]*/g,a=[],s;for(;(s=t.exec(e))!==null;)a.push({index:s.index,length:s[0].length,text:s[0],type:"url"});for(;(s=r.exec(e))!==null;){let n=s.index;a.some(m=>n>=m.index&&n<m.index+m.length)||a.push({index:n,length:s[0].length,text:s[0],type:"hashtag"});}for(;(s=o.exec(e))!==null;){let n=s.index;a.some(m=>n>=m.index&&n<m.index+m.length)||a.push({index:n,length:s[0].length,text:s[0],type:"symbol"});}a.sort((n,u)=>n.index-u.index);let i=[],d=0,c=0;return a.forEach(n=>{if(n.index>d&&i.push(e.slice(d,n.index)),n.type==="url"){let u=n.text.startsWith("http")?n.text:`https://${n.text}`;i.push(jsxRuntime.jsx("a",{href:u,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:m=>m.stopPropagation(),children:n.text},c++));}else if(n.type==="hashtag"){let m=`https://x.com/hashtag/${n.text.slice(1)}`;i.push(jsxRuntime.jsx("a",{href:m,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:T=>T.stopPropagation(),children:n.text},c++));}else n.type==="symbol"&&i.push(jsxRuntime.jsx("span",{className:"text-primary",children:n.text},c++));d=n.index+n.length;}),d<e.length&&i.push(e.slice(d)),i.length>0?i:[e]}function W({data:e,embed:t,renderActions:r}){let[o,{toggle:a}]=hooks.useBoolean(false),{t:s,i18n:i}=i18n.useTranslation(),{mutateAsync:d,isPending:c}=_(),[n,u]=react.useState(null),m=react.useCallback(async T=>{if(T.stopPropagation(),a(),!n){let I=await d({media:e,targetLanguage:i.language,options:{sourceTweet:t}}),Me=R(I);u(Me);}},[a,d,e,i.language,n,t]);return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-1 text-xs",children:[jsxRuntime.jsxs("div",{onClick:m,className:"flex items-center gap-0.5 cursor-pointer text-primary hover:text-foreground",children:[jsxRuntime.jsx(ui.TranslateIcon,{width:"14",height:"14"}),s(o?"mediaTrack.tweets.translate.hide":"mediaTrack.tweets.translate.show")]}),r]}),jsxRuntime.jsx("div",{className:ui.cn(!o&&"hidden"),onClick:T=>{T.stopPropagation();},children:o&&jsxRuntime.jsxs("div",{className:"bg-content2 rounded-md p-2 text-default-900 text-sm leading-5",children:[n,c&&jsxRuntime.jsx(ui.Skeleton,{className:"w-full h-4 rounded-md"})]})})]})}function z({isExpanded:e,onToggleExpand:t}){let{t:r}=i18n.useTranslation(),o=()=>e?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(ui.ChevronUpIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",r("mediaTrack.tweets.collapse")]}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(ui.ChevronDownIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",r("mediaTrack.tweets.expand")]});return e===void 0?null:jsxRuntime.jsxs("div",{className:"flex items-center gap-1",children:[jsxRuntime.jsx("div",{className:"w-px h-2.5 bg-line-300"}),jsxRuntime.jsx("button",{onClick:a=>{a.stopPropagation(),t?.(!e);},className:"flex items-center text-default-500 hover:text-foreground text-xs",children:o()})]})}function de({content:e,isExpanded:t=false,onLoad:r}){let o=react.useRef(null),a=react.useMemo(()=>R(e),[e]);return react.useEffect(()=>{let s=o.current;!r||!s||s.scrollHeight>s.clientHeight&&r?.();},[t,r]),jsxRuntime.jsx("div",{ref:o,className:["text-default-900 text-sm leading-5",t?"":"line-clamp-3"].join(" "),onClick:s=>{s.stopPropagation();},children:a})}function p({data:e,headerActions:t,footerActions:r,embed:o=false,indicator:a,children:s}){let[i,d]=react.useState(void 0),c=react.useMemo(()=>o?"bg-default-50 rounded-lg p-3 w-full mx-auto":"bg-default-100 hover:bg-default-200 rounded-lg p-3 w-full mx-auto",[o]),n=react.useMemo(()=>o?e.sourceTweet:e.tweet,[e,o]),u=hooks.useTickAge(n.timestamp);return jsxRuntime.jsxs("div",{className:ui.cn("flex flex-col gap-1.5 cursor-pointer",c),onClick:()=>{window.open(utils.twitterTweetUrl(n.tweetId),"_blank");},children:[jsxRuntime.jsx(B,{user:n.user,renderTimestamp:o?void 0:jsxRuntime.jsx("div",{className:"text-xs text-primary",children:utils.formatAge(u)}),renderActions:t}),a,n.content.text&&jsxRuntime.jsx(de,{content:n.content.text,isExpanded:i,onLoad:()=>d(false)}),n.content.text&&jsxRuntime.jsx(W,{data:e,embed:o,text:n.content.text,renderActions:jsxRuntime.jsx(z,{isExpanded:i,onToggleExpand:d})}),jsxRuntime.jsx("div",{className:ui.cn((!n.content.medias||n.content.medias.length===0)&&"hidden"),children:n.content.medias&&n.content.medias.length>0&&jsxRuntime.jsx(L,{medias:n.content.medias,tweetHref:utils.twitterTweetUrl(n.tweetId)})}),s,r]})}function D({data:e,headerActions:t,footerActions:r}){return jsxRuntime.jsx(p,{data:e,headerActions:t,footerActions:r})}function Q({data:e,headerActions:t,footerActions:r}){let a=!!e.sourceTweet;return jsxRuntime.jsx(p,{data:e,headerActions:t,footerActions:r,children:a?jsxRuntime.jsx(p,{data:e,embed:true}):null})}function Z({data:e,headerActions:t,footerActions:r}){let o=e.sourceTweet,a=!!o,s=react.useMemo(()=>jsxRuntime.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[jsxRuntime.jsx("span",{children:"Replying to"}),a&&jsxRuntime.jsxs(ui.Link,{className:"text-sm",underline:"hover",target:"_blank",href:utils.twitterUserUrl(o.user.screenName??o.user.username),children:["@",o.user.screenName??o.user.username]})]}),[a,o]);return jsxRuntime.jsx(p,{data:e,indicator:s,headerActions:t,footerActions:r,children:a?jsxRuntime.jsx(p,{data:e,embed:true}):null})}function J({data:e,headerActions:t,footerActions:r}){let o=e.sourceTweet,a=!!o,s=react.useMemo(()=>jsxRuntime.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[jsxRuntime.jsx("span",{children:"Retweeted by"}),a&&jsxRuntime.jsxs(ui.Link,{className:"text-sm",underline:"hover",target:"_blank",href:utils.twitterUserUrl(o.user.screenName??o.user.username),children:["@",o.user.screenName??o.user.username]})]}),[a,o]);return jsxRuntime.jsx(p,{data:e,indicator:s,headerActions:t,footerActions:r,children:a?jsxRuntime.jsx(p,{data:e,embed:true}):null})}function K({data:e,headerActions:t,footerActions:r,embed:o=false,children:a,loading:s=false}){if(s||!e)return jsxRuntime.jsx(dt,{embed:o});let i=e.tweet.type;return jsxRuntime.jsx("div",{className:"w-full",children:(()=>{let c={data:e,headerActions:t,footerActions:r,embed:o,children:a};switch(i){case "reply":return jsxRuntime.jsx(Z,{...c});case "retweet":return jsxRuntime.jsx(J,{...c});case "quote":return jsxRuntime.jsx(Q,{...c});default:return jsxRuntime.jsx(D,{...c})}})()})}function dt({embed:e=false}){return jsxRuntime.jsxs("div",{className:["flex flex-col gap-2",e?"bg-default-50 rounded-lg p-3 w-full mx-auto":"bg-default-100 rounded-lg p-3 w-full mx-auto"].join(" "),children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-3",children:[jsxRuntime.jsx(ui.Skeleton,{className:"w-10 h-10 rounded-full"}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-1 flex-1",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-24"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-3 w-16"})]}),jsxRuntime.jsx(ui.Skeleton,{className:"h-3 w-12"})]}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-2",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-full"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-3/4"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-1/2"})]}),jsxRuntime.jsx(ui.Skeleton,{className:"h-48 w-full rounded-lg"}),jsxRuntime.jsxs("div",{className:"flex justify-between items-center pt-2",children:[jsxRuntime.jsxs("div",{className:"flex gap-4",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-16"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-16"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-16"})]}),jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-20"})]})]})}function xe({token:e}){let t=new utils.SafeBigNumber(e.priceChange??"0").isPositive()?"primary":"danger";return jsxRuntime.jsxs(ui.Button,{color:t,variant:"flat",size:"sm",radius:"full",startContent:jsxRuntime.jsx(wt,{token:e}),children:[jsxRuntime.jsx("span",{children:e.symbol}),jsxRuntime.jsx("span",{children:e.priceChange?utils.formatPercent(Number(e.priceChange)/100):"--"})]})}function wt({token:e}){let t=react.useMemo(()=>jsxRuntime.jsx(ui.Image,{className:"w-full h-full",src:e.image,alt:e.chain}),[e.chain,e.image]);return jsxRuntime.jsx(ui.Badge,{className:"w-2.5 h-2.5 p-0 border",size:"sm",content:t,shape:"circle",placement:"bottom-right",children:jsxRuntime.jsx(ui.Avatar,{className:"w-5 h-5",radius:"full",src:e.image})})}function Y({data:e,loading:t,setIsPaused:r,customHeaderActions:o,customFooterActions:a}){let s=react.useCallback(i=>jsxRuntime.jsxs("div",{className:"flex gap-2.5 justify-between",children:[i.token&&jsxRuntime.jsx(xe,{token:i.token}),a?.(i)]}),[a]);return jsxRuntime.jsx("div",{className:"flex flex-col gap-2.5",onMouseEnter:()=>r(true),onMouseLeave:()=>r(false),children:e.map(i=>jsxRuntime.jsx(K,{data:i,headerActions:o?.(i),footerActions:s(i),loading:t},i.id))})}function we(){return jsxRuntime.jsxs("div",{className:"flex flex-col gap-2 bg-default-100 rounded-lg p-3 w-full mx-auto",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-3",children:[jsxRuntime.jsx(ui.Skeleton,{className:"w-10 h-10 rounded-full"}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-1 flex-1",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-40 rounded-md"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-3 w-32 rounded-md"})]})]}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-2",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-full rounded-md"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-3/4 rounded-md"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-1/2 rounded-md"})]}),jsxRuntime.jsx(ui.Skeleton,{className:"h-48 w-full rounded-lg"})]})}function j({count:e=3}){return jsxRuntime.jsx("div",{className:"flex flex-col gap-2",children:Array.from({length:e}).map((t,r)=>jsxRuntime.jsx(we,{},r))})}var te=()=>{let[e,t]=react.useState([]),[r,o]=react.useState(true),[a,s]=react.useState(false),i=H(),d=react.useCallback(c=>{t(n=>{let u=n.findIndex(T=>T.id===c.id),m;if(u>=0)m=n.map((T,I)=>I===u?c:T);else {if(a)return n;m=[c,...n];}return m.slice(0,30)}),o(false);},[a]);return react.useEffect(()=>{let c=i.subscribe("x-monitor-basic",d),n=i.subscribe("x-monitor-token",d);return ()=>{c.unsubscribe(),n.unsubscribe();}},[i,d]),{medias:e,loading:r,isPaused:a,setIsPaused:s}};function Nt({onPauseChange:e,customHeaderActions:t,customFooterActions:r}){let{medias:o,loading:a,isPaused:s,setIsPaused:i}=te();return react.useEffect(()=>{e?.(s);},[s,e]),a?jsxRuntime.jsx(j,{count:3}):jsxRuntime.jsx(Y,{data:o,loading:a,setIsPaused:i,customHeaderActions:t,customFooterActions:r})}function re(){let e=0,t=false,r=null,o=new Map;return {get generation(){return e},connect(){e+=1,t=true;},disconnect(){t=false;},setLocaleTransform(a){r=a;},subscribe(a,s){let i=o.get(a);i||(i=new Set,o.set(a,i)),i.add(s);let d=false;return {unsubscribe(){if(d)return;d=true;let c=o.get(a);c?.delete(s),c&&c.size===0&&o.delete(a);}}},publish(a,s){if(!t)return;let i=r?r(s):s;o.get(a)?.forEach(d=>d(i));}}}function Pt({client:e,children:t}){let r=react.useMemo(()=>re(),[]);return jsxRuntime.jsx(N.Provider,{value:{client:e},children:jsxRuntime.jsxs(h.Provider,{value:r,children:[jsxRuntime.jsx(At,{client:e}),t]})})}function At({client:e}){let t=react.useContext(h);return react.useEffect(()=>{if(!t)return;t.connect();let r=e.subscribeTweetMedia({callback:a=>t.publish("x-monitor-basic",a)}),o=e.subscribeTweetMediaToken({callback:a=>t.publish("x-monitor-token",a)});return ()=>{r.unsubscribe(),o.unsubscribe(),t.disconnect();}},[e,t]),null}
|
|
2
|
-
exports.MediaImage=S;exports.MediaTrackContext=N;exports.MediaTrackProvider=
|
|
1
|
+
'use strict';var hooks=require('@liberfi.io/hooks'),ui=require('@liberfi.io/ui'),jsxRuntime=require('react/jsx-runtime'),utils=require('@liberfi.io/utils'),react=require('react'),i18n=require('@liberfi.io/i18n'),reactQuery=require('@tanstack/react-query');function S({src:e}){let[t,{setTrue:o}]=hooks.useBoolean(false);return e?jsxRuntime.jsx(ui.Skeleton,{isLoaded:t,className:"w-full h-auto",children:jsxRuntime.jsx("img",{src:e,className:"w-full h-full object-cover aspect-video",onLoad:()=>{o();}})}):null}function E({src:e}){return e?jsxRuntime.jsx("div",{className:"w-full h-full overflow-hidden rounded-md mt-2",children:jsxRuntime.jsx("iframe",{className:"w-full h-full aspect-video",src:e,allowFullScreen:true})}):null}function L({medias:e,tweetHref:t}){let o=e.filter(a=>a.type==="image"),i=e.filter(a=>a.type==="video"),r=()=>i.length?jsxRuntime.jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:i.map(a=>jsxRuntime.jsx(E,{src:a.url},a.url))}):null,s=()=>o.length?jsxRuntime.jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:o.map(a=>jsxRuntime.jsx(ui.Link,{href:t,target:"_blank",children:jsxRuntime.jsx(S,{src:a.url})},a.url))}):null;return jsxRuntime.jsxs("div",{className:"flex flex-col gap-2",children:[r(),s()]})}function U({url:e,name:t="",size:o=36}){let i=react.useMemo(()=>t?t.slice(0,2):"N/A",[t]);return jsxRuntime.jsx(ui.Skeleton,{className:"flex rounded-full flex-shrink-0",style:{width:o,height:o},isLoaded:!!e,children:jsxRuntime.jsx(ui.Avatar,{size:"md",color:"primary",radius:"full",showFallback:true,name:i,src:e,style:{width:o,height:o}})})}function B({user:e,renderTimestamp:t,renderActions:o}){return jsxRuntime.jsxs("div",{className:"flex items-center justify-between gap-1",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-1",children:[jsxRuntime.jsx(U,{url:e.avatar,name:e.username}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxRuntime.jsxs("div",{className:"flex flex-row items-baseline gap-1",children:[jsxRuntime.jsx("span",{className:"text-foreground font-semibold truncate leading-none",children:e.username}),t]}),jsxRuntime.jsxs(ui.Link,{target:"_blank",underline:"hover",className:"text-text-muted text-sm leading-none",href:utils.twitterUserUrl(e.screenName??e.username),children:["@",e.screenName??e.username]})]})]}),o]})}var N=react.createContext({});var h=react.createContext(null);function O(){let e=react.useContext(N);if(!e)throw new Error("useMediaTrackContext must be used within a MediaTrackProvider");return e}function y(){let{client:e}=O();return e}function Ue(e={}){let t=y();return reactQuery.useMutation({mutationFn:async o=>t.generateMeme(o),...e})}function H(){let e=react.useContext(h);if(!e)throw new Error("useMediaTrackRuntime must be used within a MediaTrackProvider");return e}async function se(e,{media:t,targetLanguage:o,options:i}){return await e.translate(t,o,i)}function _(e={}){let t=y();return reactQuery.useMutation({mutationFn:async o=>se(t,o),...e})}function R(e){let t=/(https?:\/\/[^\s]+|www\.[^\s]+)/gi,o=/#[\w]+/g,i=/\$[A-Za-z][A-Za-z0-9_]*/g,r=[],s;for(;(s=t.exec(e))!==null;)r.push({index:s.index,length:s[0].length,text:s[0],type:"url"});for(;(s=o.exec(e))!==null;){let n=s.index;r.some(m=>n>=m.index&&n<m.index+m.length)||r.push({index:n,length:s[0].length,text:s[0],type:"hashtag"});}for(;(s=i.exec(e))!==null;){let n=s.index;r.some(m=>n>=m.index&&n<m.index+m.length)||r.push({index:n,length:s[0].length,text:s[0],type:"symbol"});}r.sort((n,p)=>n.index-p.index);let a=[],d=0,c=0;return r.forEach(n=>{if(n.index>d&&a.push(e.slice(d,n.index)),n.type==="url"){let p=n.text.startsWith("http")?n.text:`https://${n.text}`;a.push(jsxRuntime.jsx("a",{href:p,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:m=>m.stopPropagation(),children:n.text},c++));}else if(n.type==="hashtag"){let m=`https://x.com/hashtag/${n.text.slice(1)}`;a.push(jsxRuntime.jsx("a",{href:m,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:T=>T.stopPropagation(),children:n.text},c++));}else n.type==="symbol"&&a.push(jsxRuntime.jsx("span",{className:"text-primary",children:n.text},c++));d=n.index+n.length;}),d<e.length&&a.push(e.slice(d)),a.length>0?a:[e]}function W({data:e,embed:t,renderActions:o}){let[i,{toggle:r}]=hooks.useBoolean(false),{t:s,i18n:a}=i18n.useTranslation(),{mutateAsync:d,isPending:c}=_(),[n,p]=react.useState(null),m=react.useCallback(async T=>{if(T.stopPropagation(),r(),!n){let I=await d({media:e,targetLanguage:a.language,options:{sourceTweet:t}}),Me=R(I);p(Me);}},[r,d,e,a.language,n,t]);return jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-1 text-xs",children:[jsxRuntime.jsxs("div",{onClick:m,className:"flex items-center gap-0.5 cursor-pointer text-primary hover:text-foreground",children:[jsxRuntime.jsx(ui.TranslateIcon,{width:"14",height:"14"}),s(i?"mediaTrack.tweets.translate.hide":"mediaTrack.tweets.translate.show")]}),o]}),jsxRuntime.jsx("div",{className:ui.cn(!i&&"hidden"),onClick:T=>{T.stopPropagation();},children:i&&jsxRuntime.jsxs("div",{className:"bg-content2 rounded-md p-2 text-text-primary text-sm leading-5",children:[n,c&&jsxRuntime.jsx(ui.Skeleton,{className:"w-full h-4 rounded-md"})]})})]})}function z({isExpanded:e,onToggleExpand:t}){let{t:o}=i18n.useTranslation(),i=()=>e?jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(ui.ChevronUpIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",o("mediaTrack.tweets.collapse")]}):jsxRuntime.jsxs(jsxRuntime.Fragment,{children:[jsxRuntime.jsx(ui.ChevronDownIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",o("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:r=>{r.stopPropagation(),t?.(!e);},className:"flex items-center text-text-muted hover:text-foreground text-xs",children:i()})]})}function de({content:e,isExpanded:t=false,onLoad:o}){let i=react.useRef(null),r=react.useMemo(()=>R(e),[e]);return react.useEffect(()=>{let s=i.current;!o||!s||s.scrollHeight>s.clientHeight&&o?.();},[t,o]),jsxRuntime.jsx("div",{ref:i,className:["text-text-primary text-sm leading-5",t?"":"line-clamp-3"].join(" "),onClick:s=>{s.stopPropagation();},children:r})}function u({data:e,headerActions:t,footerActions:o,embed:i=false,indicator:r,children:s}){let[a,d]=react.useState(void 0),c=react.useMemo(()=>i?"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",[i]),n=react.useMemo(()=>i?e.sourceTweet:e.tweet,[e,i]),p=hooks.useTickAge(n.timestamp);return jsxRuntime.jsxs("div",{className:ui.cn("flex flex-col gap-1.5 cursor-pointer",c),onClick:()=>{window.open(utils.twitterTweetUrl(n.tweetId),"_blank");},children:[jsxRuntime.jsx(B,{user:n.user,renderTimestamp:i?void 0:jsxRuntime.jsx("div",{className:"text-xs text-primary",children:utils.formatAge(p)}),renderActions:t}),r,n.content.text&&jsxRuntime.jsx(de,{content:n.content.text,isExpanded:a,onLoad:()=>d(false)}),n.content.text&&jsxRuntime.jsx(W,{data:e,embed:i,text:n.content.text,renderActions:jsxRuntime.jsx(z,{isExpanded:a,onToggleExpand:d})}),jsxRuntime.jsx("div",{className:ui.cn((!n.content.medias||n.content.medias.length===0)&&"hidden"),children:n.content.medias&&n.content.medias.length>0&&jsxRuntime.jsx(L,{medias:n.content.medias,tweetHref:utils.twitterTweetUrl(n.tweetId)})}),s,o]})}function D({data:e,headerActions:t,footerActions:o}){return jsxRuntime.jsx(u,{data:e,headerActions:t,footerActions:o})}function Q({data:e,headerActions:t,footerActions:o}){let r=!!e.sourceTweet;return jsxRuntime.jsx(u,{data:e,headerActions:t,footerActions:o,children:r?jsxRuntime.jsx(u,{data:e,embed:true}):null})}function Z({data:e,headerActions:t,footerActions:o}){let{t:i}=i18n.useTranslation(),r=e.sourceTweet,s=!!r,a=react.useMemo(()=>jsxRuntime.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[jsxRuntime.jsx("span",{children:i("mediaTrack.replyingTo")}),s&&jsxRuntime.jsxs(ui.Link,{className:"text-sm",underline:"hover",target:"_blank",href:utils.twitterUserUrl(r.user.screenName??r.user.username),children:["@",r.user.screenName??r.user.username]})]}),[s,r,i]);return jsxRuntime.jsx(u,{data:e,indicator:a,headerActions:t,footerActions:o,children:s?jsxRuntime.jsx(u,{data:e,embed:true}):null})}function J({data:e,headerActions:t,footerActions:o}){let{t:i}=i18n.useTranslation(),r=e.sourceTweet,s=!!r,a=react.useMemo(()=>jsxRuntime.jsxs("div",{className:"flex items-center gap-2 text-sm",children:[jsxRuntime.jsx("span",{children:i("mediaTrack.retweetedBy")}),s&&jsxRuntime.jsxs(ui.Link,{className:"text-sm",underline:"hover",target:"_blank",href:utils.twitterUserUrl(r.user.screenName??r.user.username),children:["@",r.user.screenName??r.user.username]})]}),[s,r,i]);return jsxRuntime.jsx(u,{data:e,indicator:a,headerActions:t,footerActions:o,children:s?jsxRuntime.jsx(u,{data:e,embed:true}):null})}function K({data:e,headerActions:t,footerActions:o,embed:i=false,children:r,loading:s=false}){if(s||!e)return jsxRuntime.jsx(mt,{embed:i});let a=e.tweet.type;return jsxRuntime.jsx("div",{className:"w-full",children:(()=>{let c={data:e,headerActions:t,footerActions:o,embed:i,children:r};switch(a){case "reply":return jsxRuntime.jsx(Z,{...c});case "retweet":return jsxRuntime.jsx(J,{...c});case "quote":return jsxRuntime.jsx(Q,{...c});default:return jsxRuntime.jsx(D,{...c})}})()})}function mt({embed:e=false}){return jsxRuntime.jsxs("div",{className:["flex flex-col gap-2",e?"bg-default-50 rounded-lg p-3 w-full mx-auto":"bg-default-100 rounded-lg p-3 w-full mx-auto"].join(" "),children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-3",children:[jsxRuntime.jsx(ui.Skeleton,{className:"w-10 h-10 rounded-full"}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-1 flex-1",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-24"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-3 w-16"})]}),jsxRuntime.jsx(ui.Skeleton,{className:"h-3 w-12"})]}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-2",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-full"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-3/4"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-1/2"})]}),jsxRuntime.jsx(ui.Skeleton,{className:"h-48 w-full rounded-lg"}),jsxRuntime.jsxs("div",{className:"flex justify-between items-center pt-2",children:[jsxRuntime.jsxs("div",{className:"flex gap-4",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-16"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-16"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-16"})]}),jsxRuntime.jsx(ui.Skeleton,{className:"h-6 w-20"})]})]})}function xe({token:e}){let t=new utils.SafeBigNumber(e.priceChange??"0").isPositive()?"primary":"danger";return jsxRuntime.jsxs(ui.Button,{color:t,variant:"flat",size:"sm",radius:"full",startContent:jsxRuntime.jsx(ht,{token:e}),children:[jsxRuntime.jsx("span",{children:e.symbol}),jsxRuntime.jsx("span",{children:e.priceChange?utils.formatPercent(Number(e.priceChange)/100):"--"})]})}function ht({token:e}){let t=react.useMemo(()=>jsxRuntime.jsx(ui.Image,{className:"w-full h-full",src:e.image,alt:e.chain}),[e.chain,e.image]);return jsxRuntime.jsx(ui.Badge,{className:"w-2.5 h-2.5 p-0 border",size:"sm",content:t,shape:"circle",placement:"bottom-right",children:jsxRuntime.jsx(ui.Avatar,{className:"w-5 h-5",radius:"full",src:e.image})})}function Y({data:e,loading:t,setIsPaused:o,customHeaderActions:i,customFooterActions:r}){let s=react.useCallback(a=>jsxRuntime.jsxs("div",{className:"flex gap-2.5 justify-between",children:[a.token&&jsxRuntime.jsx(xe,{token:a.token}),r?.(a)]}),[r]);return jsxRuntime.jsx("div",{className:"flex flex-col gap-2.5",onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),children:e.map(a=>jsxRuntime.jsx(K,{data:a,headerActions:i?.(a),footerActions:s(a),loading:t},a.id))})}function we(){return jsxRuntime.jsxs("div",{className:"flex flex-col gap-2 bg-default-100 rounded-lg p-3 w-full mx-auto",children:[jsxRuntime.jsxs("div",{className:"flex items-center gap-3",children:[jsxRuntime.jsx(ui.Skeleton,{className:"w-10 h-10 rounded-full"}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-1 flex-1",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-40 rounded-md"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-3 w-32 rounded-md"})]})]}),jsxRuntime.jsxs("div",{className:"flex flex-col gap-2",children:[jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-full rounded-md"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-3/4 rounded-md"}),jsxRuntime.jsx(ui.Skeleton,{className:"h-4 w-1/2 rounded-md"})]}),jsxRuntime.jsx(ui.Skeleton,{className:"h-48 w-full rounded-lg"})]})}function j({count:e=3}){return jsxRuntime.jsx("div",{className:"flex flex-col gap-2",children:Array.from({length:e}).map((t,o)=>jsxRuntime.jsx(we,{},o))})}var te=()=>{let[e,t]=react.useState([]),[o,i]=react.useState(true),[r,s]=react.useState(false),a=H(),d=react.useCallback(c=>{t(n=>{let p=n.findIndex(T=>T.id===c.id),m;if(p>=0)m=n.map((T,I)=>I===p?c:T);else {if(r)return n;m=[c,...n];}return m.slice(0,30)}),i(false);},[r]);return react.useEffect(()=>{let c=a.subscribe("x-monitor-basic",d),n=a.subscribe("x-monitor-token",d);return ()=>{c.unsubscribe(),n.unsubscribe();}},[a,d]),{medias:e,loading:o,isPaused:r,setIsPaused:s}};function Rt({onPauseChange:e,customHeaderActions:t,customFooterActions:o}){let{medias:i,loading:r,isPaused:s,setIsPaused:a}=te();return react.useEffect(()=>{e?.(s);},[s,e]),r?jsxRuntime.jsx(j,{count:3}):jsxRuntime.jsx(Y,{data:i,loading:r,setIsPaused:a,customHeaderActions:t,customFooterActions:o})}function re(){let e=0,t=false,o=null,i=new Map;return {get generation(){return e},connect(){e+=1,t=true;},disconnect(){t=false;},setLocaleTransform(r){o=r;},subscribe(r,s){let a=i.get(r);a||(a=new Set,i.set(r,a)),a.add(s);let d=false;return {unsubscribe(){if(d)return;d=true;let c=i.get(r);c?.delete(s),c&&c.size===0&&i.delete(r);}}},publish(r,s){if(!t)return;let a=o?o(s):s;i.get(r)?.forEach(d=>d(a));}}}function It({client:e,children:t}){let o=react.useMemo(()=>re(),[]);return jsxRuntime.jsx(N.Provider,{value:{client:e},children:jsxRuntime.jsxs(h.Provider,{value:o,children:[jsxRuntime.jsx(St,{client:e}),t]})})}function St({client:e}){let t=react.useContext(h);return react.useEffect(()=>{if(!t)return;t.connect();let o=e.subscribeTweetMedia({callback:r=>t.publish("x-monitor-basic",r)}),i=e.subscribeTweetMediaToken({callback:r=>t.publish("x-monitor-token",r)});return ()=>{o.unsubscribe(),i.unsubscribe(),t.disconnect();}},[e,t]),null}
|
|
2
|
+
exports.MediaImage=S;exports.MediaTrackContext=N;exports.MediaTrackProvider=It;exports.MediaTrackRuntimeContext=h;exports.MediaVideo=E;exports.Medias=L;exports.TextExpand=z;exports.Translate=W;exports.TweetItem=K;exports.TweetOriginal=D;exports.TweetQuote=Q;exports.TweetReply=Z;exports.TweetRetweet=J;exports.TweetSkeleton=we;exports.TweetSkeletonList=j;exports.TweetSource=u;exports.Tweets=Y;exports.TweetsWidget=Rt;exports.UserAvatar=U;exports.UserInfo=B;exports.createMediaTrackRuntime=re;exports.translateTweetMedia=se;exports.useGenerateTweetMediaMemeMutation=Ue;exports.useMediaTrackClient=y;exports.useMediaTrackContext=O;exports.useMediaTrackRuntime=H;exports.useTranslateTweetMediaMutation=_;exports.useTweets=te;//# sourceMappingURL=index.js.map
|
|
3
3
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/tweets/tweet/media/media-image.tsx","../src/components/tweets/tweet/media/media-video.tsx","../src/components/tweets/tweet/media/medias.tsx","../src/components/tweets/tweet/user/user-avatar.tsx","../src/components/tweets/tweet/user/user-info.tsx","../src/context/MediaTrackContext.ts","../src/context/MediaTrackRuntimeContext.ts","../src/hooks/useMediaTrackContext.ts","../src/hooks/useMediaTrackClient.ts","../src/hooks/useGenerateTweetMediaMemeMutation.ts","../src/hooks/useMediaTrackRuntime.ts","../src/hooks/useTranslateTweetMediaQuery.ts","../src/utils/parseText.tsx","../src/components/tweets/tweet/tools/translate.tsx","../src/components/tweets/tweet/tools/text-expand.tsx","../src/components/tweets/tweet/content/index.tsx","../src/components/tweets/tweet/tweet-source.tsx","../src/components/tweets/tweet/tweet-original.tsx","../src/components/tweets/tweet/tweet-quote.tsx","../src/components/tweets/tweet/tweet-reply.tsx","../src/components/tweets/tweet/tweet-retweet.tsx","../src/components/tweets/tweet/tweet-item.tsx","../src/components/tweets/tweet/tools/tweet-token-button.tsx","../src/components/tweets/tweets.ui.tsx","../src/components/tweets/tweet/tweet-skeleton.tsx","../src/components/tweets/tweets.script.ts","../src/components/tweets/tweets.widget.tsx","../src/runtime/media-track-runtime.ts","../src/providers/MediaTrackProvider.tsx"],"names":["MediaImage","src","isLoaded","setTrue","useBoolean","jsx","Skeleton","MediaVideo","Medias","medias","tweetHref","images","media","videos","renderVideos","video","renderImages","image","Link","jsxs","UserAvatar","url","name","size","fallbackName","useMemo","Avatar","UserInfo","user","renderTimestamp","renderActions","twitterUserUrl","MediaTrackContext","createContext","MediaTrackRuntimeContext","useMediaTrackContext","context","useContext","useMediaTrackClient","client","useGenerateTweetMediaMemeMutation","options","useMutation","params","useMediaTrackRuntime","runtime","translateTweetMedia","targetLanguage","useTranslateTweetMediaMutation","parseText","text","urlRegex","hashtagRegex","symbolRegex","matches","match","matchIndex","a","b","parts","lastIndex","key","item","e","hashtagUrl","Translate","data","embed","isTranslate","toggle","t","i18n","useTranslation","isTranslating","translatedText","setTranslatedText","useState","handleTranslate","useCallback","parsedText","Fragment","TranslateIcon","cn","TextExpand","isExpanded","onToggleExpand","renderExpand","ChevronUpIcon","ChevronDownIcon","Content","content","onLoad","ref","useRef","parsedContent","useEffect","current","TweetSource","headerActions","footerActions","indicator","children","setIsExpanded","containerClass","tweet","age","useTickAge","twitterTweetUrl","formatAge","TweetOriginal","TweetQuote","hasSource","TweetReply","sourceTweet","TweetRetweet","TweetItem","loading","TweetSkeleton","tweetType","commonProps","TweetTokenButton","token","color","SafeBigNumber","Button","TweetTokenIcon","formatPercent","ChainIcon","Image","Badge","Tweets","setIsPaused","customHeaderActions","customFooterActions","TweetSkeletonList","count","_","index","useTweets","setMedias","setLoading","isPaused","handleMedia","prevMedias","idx","it","newMedias","subTweet","subTweetToken","TweetsWidget","onPauseChange","createMediaTrackRuntime","generation","connected","localeTransform","listeners","transform","channel","listener","bucket","unsubscribed","payload","next","MediaTrackProvider","MediaTrackClientBridge","basic"],"mappings":"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","file":"index.js","sourcesContent":["import { useBoolean } from \"@liberfi.io/hooks\";\nimport { Skeleton } from \"@liberfi.io/ui\";\n\ntype Props = {\n src: string;\n};\n\n// ------------------------------------------------------------\nexport function MediaImage({ src }: Props) {\n const [isLoaded, { setTrue }] = useBoolean(false);\n if (!src) return null;\n\n return (\n <Skeleton isLoaded={isLoaded} className=\"w-full h-auto\">\n <img\n src={src}\n className=\"w-full h-full object-cover aspect-video\"\n onLoad={() => {\n setTrue();\n }}\n />\n </Skeleton>\n );\n}\n","type Props = {\n src: string;\n};\n\n// ------------------------------------------------------------\nexport function MediaVideo({ src }: Props) {\n if (!src) return null;\n\n return (\n <div className=\"w-full h-full overflow-hidden rounded-md mt-2\">\n <iframe\n className=\"w-full h-full aspect-video\"\n src={src}\n allowFullScreen\n />\n </div>\n );\n}\n","import { Link } from \"@liberfi.io/ui\";\nimport { TweetContentMedia } from \"../../../../types\";\nimport { MediaImage } from \"./media-image\";\nimport { MediaVideo } from \"./media-video\";\n\ntype Props = {\n medias: Array<TweetContentMedia>;\n tweetHref: string;\n};\n\nexport function Medias({ medias, tweetHref }: Props) {\n const images = medias.filter((media) => media.type === \"image\");\n const videos = medias.filter((media) => media.type === \"video\");\n\n const renderVideos = () => {\n if (!videos.length) return null;\n return (\n <div className={`grid grid-cols-1 gap-[1px] overflow-hidden rounded-md`}>\n {videos.map((video) => (\n <MediaVideo key={video.url} src={video.url} />\n ))}\n </div>\n );\n };\n\n const renderImages = () => {\n if (!images.length) return null;\n return (\n <div className={`grid grid-cols-1 gap-[1px] overflow-hidden rounded-md`}>\n {images.map((image) => (\n <Link key={image.url} href={tweetHref} target=\"_blank\">\n <MediaImage src={image.url} />\n </Link>\n ))}\n </div>\n );\n };\n\n return (\n <div className=\"flex flex-col gap-2\">\n {renderVideos()}\n {renderImages()}\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { Avatar, Skeleton } from \"@liberfi.io/ui\";\n\ntype Props = {\n url?: string;\n name?: string;\n size?: number;\n};\n\nexport function UserAvatar({ url, name = \"\", size = 36 }: Props) {\n const fallbackName = useMemo(() => (name ? name.slice(0, 2) : \"N/A\"), [name]);\n\n return (\n <Skeleton\n className=\"flex rounded-full flex-shrink-0\"\n style={{ width: size, height: size }}\n isLoaded={!!url}\n >\n <Avatar\n size=\"md\"\n color=\"primary\"\n radius=\"full\"\n showFallback\n name={fallbackName}\n src={url}\n style={{ width: size, height: size }}\n />\n </Skeleton>\n );\n}\n","import React from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetUser } from \"../../../../types\";\nimport { UserAvatar } from \"./user-avatar\";\n\ntype Props = {\n user: TweetUser;\n renderTimestamp?: React.ReactNode;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function UserInfo({ user, renderTimestamp, renderActions }: Props) {\n return (\n <div className=\"flex items-center justify-between gap-1\">\n <div className=\"flex items-center gap-1\">\n <UserAvatar url={user.avatar} name={user.username} />\n <div className=\"flex flex-col gap-0.5\">\n <div className=\"flex flex-row items-baseline gap-1\">\n <span className=\"text-foreground font-semibold truncate leading-none\">\n {user.username}\n </span>\n {renderTimestamp}\n </div>\n <Link\n target=\"_blank\"\n underline=\"hover\"\n className=\"text-default-500 text-sm leading-none\"\n href={twitterUserUrl(user.screenName ?? user.username)}\n >\n @{user.screenName ?? user.username}\n </Link>\n </div>\n </div>\n {renderActions}\n </div>\n );\n}\n","import { createContext } from \"react\";\nimport { IMediaTrackClient } from \"../types\";\n\nexport interface MediaTrackContextValue {\n client: IMediaTrackClient;\n}\n\nexport const MediaTrackContext = createContext<MediaTrackContextValue>(\n {} as MediaTrackContextValue,\n);\n","import { createContext } from \"react\";\nimport type { TweetMedia } from \"../types\";\nimport type { MediaTrackRuntime } from \"../runtime/media-track-runtime\";\n\nexport const MediaTrackRuntimeContext =\n createContext<MediaTrackRuntime<TweetMedia> | null>(null);\n","import { useContext } from \"react\";\nimport { MediaTrackContext } from \"../context\";\n\nexport function useMediaTrackContext() {\n const context = useContext(MediaTrackContext);\n if (!context) {\n throw new Error(\n \"useMediaTrackContext must be used within a MediaTrackProvider\",\n );\n }\n return context;\n}\n","import { useMediaTrackContext } from \"./useMediaTrackContext\";\n\nexport function useMediaTrackClient() {\n const { client } = useMediaTrackContext();\n return client;\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport { GeneratedMemeInfo, TweetMedia } from \"../types\";\nimport { useMediaTrackClient } from \"./useMediaTrackClient\";\n\nexport function useGenerateTweetMediaMemeMutation(\n options: Omit<\n UseMutationOptions<GeneratedMemeInfo, Error, TweetMedia, string[]>,\n \"mutationFn\"\n > = {},\n) {\n const client = useMediaTrackClient();\n return useMutation({\n mutationFn: async (params: TweetMedia) => client.generateMeme(params),\n ...options,\n });\n}\n","import { useContext } from \"react\";\nimport { MediaTrackRuntimeContext } from \"../context/MediaTrackRuntimeContext\";\n\nexport function useMediaTrackRuntime() {\n const runtime = useContext(MediaTrackRuntimeContext);\n if (!runtime) {\n throw new Error(\n \"useMediaTrackRuntime must be used within a MediaTrackProvider\",\n );\n }\n return runtime;\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport { LocaleCode } from \"@liberfi.io/i18n\";\nimport { IMediaTrackClient, TweetMedia } from \"../types\";\nimport { useMediaTrackClient } from \"./useMediaTrackClient\";\n\nexport interface UseTranslateTweetMediaParams {\n media: TweetMedia;\n targetLanguage: LocaleCode;\n options?: {\n sourceLanguage?: LocaleCode;\n sourceTweet?: boolean;\n };\n}\n\nexport async function translateTweetMedia(\n client: IMediaTrackClient,\n { media, targetLanguage, options }: UseTranslateTweetMediaParams,\n) {\n return await client.translate(media, targetLanguage, options);\n}\n\nexport function useTranslateTweetMediaMutation(\n options: Omit<\n UseMutationOptions<string, Error, UseTranslateTweetMediaParams>,\n \"mutationFn\"\n > = {},\n) {\n const client = useMediaTrackClient();\n return useMutation({\n mutationFn: async (params: UseTranslateTweetMediaParams) =>\n translateTweetMedia(client, params),\n ...options,\n });\n}\n","interface MatchItem {\n index: number;\n length: number;\n text: string;\n type: \"url\" | \"hashtag\" | \"symbol\";\n}\n\nexport function parseText(text: string): (string | React.ReactElement)[] {\n const urlRegex = /(https?:\\/\\/[^\\s]+|www\\.[^\\s]+)/gi;\n const hashtagRegex = /#[\\w]+/g;\n const symbolRegex = /\\$[A-Za-z][A-Za-z0-9_]*/g;\n\n const matches: MatchItem[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = urlRegex.exec(text)) !== null) {\n matches.push({\n index: match.index,\n length: match[0].length,\n text: match[0],\n type: \"url\",\n });\n }\n\n while ((match = hashtagRegex.exec(text)) !== null) {\n const matchIndex = match.index;\n const overlaps = matches.some(\n (m) => matchIndex >= m.index && matchIndex < m.index + m.length,\n );\n if (!overlaps) {\n matches.push({\n index: matchIndex,\n length: match[0].length,\n text: match[0],\n type: \"hashtag\",\n });\n }\n }\n\n while ((match = symbolRegex.exec(text)) !== null) {\n const matchIndex = match.index;\n const overlaps = matches.some(\n (m) => matchIndex >= m.index && matchIndex < m.index + m.length,\n );\n if (!overlaps) {\n matches.push({\n index: matchIndex,\n length: match[0].length,\n text: match[0],\n type: \"symbol\",\n });\n }\n }\n\n matches.sort((a, b) => a.index - b.index);\n\n const parts: (string | React.ReactElement)[] = [];\n let lastIndex = 0;\n let key = 0;\n\n matches.forEach((item) => {\n if (item.index > lastIndex) {\n parts.push(text.slice(lastIndex, item.index));\n }\n\n if (item.type === \"url\") {\n const url = item.text.startsWith(\"http\")\n ? item.text\n : `https://${item.text}`;\n parts.push(\n <a\n key={key++}\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline\"\n onClick={(e) => e.stopPropagation()}\n >\n {item.text}\n </a>,\n );\n } else if (item.type === \"hashtag\") {\n const hashtag = item.text.slice(1); // 移除 #\n const hashtagUrl = `https://x.com/hashtag/${hashtag}`;\n parts.push(\n <a\n key={key++}\n href={hashtagUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline\"\n onClick={(e) => e.stopPropagation()}\n >\n {item.text}\n </a>,\n );\n } else if (item.type === \"symbol\") {\n parts.push(\n <span key={key++} className=\"text-primary\">\n {item.text}\n </span>,\n );\n }\n\n lastIndex = item.index + item.length;\n });\n\n if (lastIndex < text.length) {\n parts.push(text.slice(lastIndex));\n }\n\n return parts.length > 0 ? parts : [text];\n}\n","import React, { MouseEvent, useCallback, useState } from \"react\";\nimport { useBoolean } from \"@liberfi.io/hooks\";\nimport { LocaleCode, useTranslation } from \"@liberfi.io/i18n\";\nimport { cn, Skeleton, TranslateIcon } from \"@liberfi.io/ui\";\nimport { useTranslateTweetMediaMutation } from \"../../../../hooks\";\nimport { TweetMedia } from \"../../../../types\";\nimport { parseText } from \"../../../../utils\";\n\ntype Props = {\n data: TweetMedia;\n embed?: boolean;\n text: string;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function Translate({ data, embed, renderActions }: Props) {\n const [isTranslate, { toggle }] = useBoolean(false);\n\n const { t, i18n } = useTranslation();\n\n const { mutateAsync: translateTweetMedia, isPending: isTranslating } =\n useTranslateTweetMediaMutation();\n\n const [translatedText, setTranslatedText] = useState<\n (string | React.ReactElement)[] | null\n >(null);\n\n const handleTranslate = useCallback(\n async (e: MouseEvent<HTMLDivElement>) => {\n e.stopPropagation();\n toggle();\n if (!translatedText) {\n const text = await translateTweetMedia({\n media: data,\n targetLanguage: i18n.language as LocaleCode,\n options: {\n sourceTweet: embed,\n },\n });\n const parsedText = parseText(text);\n setTranslatedText(parsedText);\n }\n },\n [toggle, translateTweetMedia, data, i18n.language, translatedText, embed],\n );\n\n return (\n <>\n <div className=\"flex items-center gap-1 text-xs\">\n <div\n onClick={handleTranslate}\n className=\"flex items-center gap-0.5 cursor-pointer text-primary hover:text-foreground\"\n >\n <TranslateIcon width=\"14\" height=\"14\" />\n {isTranslate\n ? t(\"mediaTrack.tweets.translate.hide\")\n : t(\"mediaTrack.tweets.translate.show\")}\n </div>\n {renderActions}\n </div>\n <div\n className={cn(!isTranslate && \"hidden\")}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n {isTranslate && (\n <div className=\"bg-content2 rounded-md p-2 text-default-900 text-sm leading-5\">\n {translatedText}\n {isTranslating && <Skeleton className=\"w-full h-4 rounded-md\" />}\n </div>\n )}\n </div>\n </>\n );\n}\n","import { useTranslation } from \"@liberfi.io/i18n\";\nimport { ChevronDownIcon, ChevronUpIcon } from \"@liberfi.io/ui\";\n\ntype Props = {\n isExpanded?: boolean;\n onToggleExpand?: (expanded: boolean) => void;\n};\n\nexport function TextExpand({ isExpanded, onToggleExpand }: Props) {\n const { t } = useTranslation();\n const renderExpand = () => {\n if (isExpanded) {\n return (\n <>\n <ChevronUpIcon\n className=\"border border-current\"\n width=\"12\"\n height=\"12\"\n />\n {t(\"mediaTrack.tweets.collapse\")}\n </>\n );\n }\n\n return (\n <>\n <ChevronDownIcon\n className=\"border border-current\"\n width=\"12\"\n height=\"12\"\n />\n {t(\"mediaTrack.tweets.expand\")}\n </>\n );\n };\n\n if (isExpanded === undefined) return null;\n\n return (\n <div className=\"flex items-center gap-1\">\n <div className=\"w-px h-2.5 bg-line-300\" />\n <button\n onClick={(e) => {\n e.stopPropagation();\n onToggleExpand?.(!isExpanded);\n }}\n className=\"flex items-center text-default-500 hover:text-foreground text-xs\"\n >\n {renderExpand()}\n </button>\n </div>\n );\n}\n","import { useEffect, useMemo, useRef } from \"react\";\nimport { parseText } from \"../../../../utils\";\n\ntype Props = {\n content: string;\n isExpanded?: boolean;\n onLoad?: () => void;\n};\n\n// ------------------------------------------------------------\nexport function Content({ content, isExpanded = false, onLoad }: Props) {\n const ref = useRef<HTMLDivElement>(null);\n\n const parsedContent = useMemo(() => parseText(content), [content]);\n\n useEffect(() => {\n const current = ref.current;\n if (!onLoad || !current) return;\n if (current.scrollHeight > current.clientHeight) {\n onLoad?.();\n }\n }, [isExpanded, onLoad]);\n\n return (\n <div\n ref={ref}\n className={[\n \"text-default-900 text-sm leading-5\",\n !isExpanded ? \"line-clamp-3\" : \"\",\n ].join(\" \")}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n {parsedContent}\n </div>\n );\n}\n","import React, { useMemo, useState } from \"react\";\nimport { useTickAge } from \"@liberfi.io/hooks\";\nimport { cn } from \"@liberfi.io/ui\";\nimport { formatAge, twitterTweetUrl } from \"@liberfi.io/utils\";\nimport { Tweet, TweetMedia } from \"../../../types\";\nimport { Content } from \"./content\";\nimport { Medias } from \"./media\";\nimport { Translate, TextExpand } from \"./tools\";\nimport { UserInfo } from \"./user\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n embed?: boolean;\n indicator?: React.ReactNode;\n children?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetSource({\n data,\n headerActions,\n footerActions,\n embed = false,\n indicator,\n children,\n}: Props) {\n const [isExpanded, setIsExpanded] = useState<boolean | undefined>(undefined);\n\n const containerClass = useMemo(() => {\n return embed\n ? \"bg-default-50 rounded-lg p-3 w-full mx-auto\"\n : \"bg-default-100 hover:bg-default-200 rounded-lg p-3 w-full mx-auto\";\n }, [embed]);\n\n const tweet = useMemo(\n () => (embed ? data.sourceTweet! : data.tweet),\n [data, embed],\n );\n\n const age = useTickAge((tweet as Tweet).timestamp);\n\n return (\n <div\n className={cn(\"flex flex-col gap-1.5 cursor-pointer\", containerClass)}\n onClick={() => {\n window.open(twitterTweetUrl(tweet.tweetId), \"_blank\");\n }}\n >\n {/* -------- USER INFO -------- */}\n <UserInfo\n user={tweet.user}\n renderTimestamp={\n embed ? undefined : (\n <div className=\"text-xs text-primary\">{formatAge(age)}</div>\n )\n }\n renderActions={headerActions}\n />\n\n {/* -------- MESSAGE TYPE INDICATOR -------- */}\n {indicator}\n\n {/* -------- CONTENT -------- */}\n {tweet.content.text && (\n <Content\n content={tweet.content.text}\n isExpanded={isExpanded}\n onLoad={() => setIsExpanded(false)}\n />\n )}\n\n {/* -------- TOOLS -------- */}\n {tweet.content.text && (\n <Translate\n data={data}\n embed={embed}\n text={tweet.content.text}\n renderActions={\n <TextExpand\n isExpanded={isExpanded}\n onToggleExpand={setIsExpanded}\n />\n }\n />\n )}\n\n {/* -------- MEDIA -------- */}\n <div\n className={cn(\n (!tweet.content.medias || tweet.content.medias.length === 0) &&\n \"hidden\",\n )}\n >\n {tweet.content.medias && tweet.content.medias.length > 0 && (\n <Medias\n medias={tweet.content.medias}\n tweetHref={twitterTweetUrl(tweet.tweetId)}\n />\n )}\n </div>\n\n {/* -------- CHILDREN -------- */}\n {children}\n\n {/* -------- Custom ACTIONS -------- */}\n {footerActions}\n </div>\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetOriginal({ data, headerActions, footerActions }: Props) {\n return (\n <TweetSource\n data={data}\n headerActions={headerActions}\n footerActions={footerActions}\n />\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetQuote({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n return (\n <TweetSource\n data={data}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetReply({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n const indicator = useMemo(\n () => (\n <div className=\"flex items-center gap-2 text-sm\">\n <span>Replying to</span>\n {hasSource && (\n <Link\n className=\"text-sm\"\n underline=\"hover\"\n target=\"_blank\"\n href={twitterUserUrl(\n sourceTweet.user.screenName ?? sourceTweet.user.username,\n )}\n >\n @{sourceTweet.user.screenName ?? sourceTweet.user.username}\n </Link>\n )}\n </div>\n ),\n [hasSource, sourceTweet],\n );\n\n return (\n <TweetSource\n data={data}\n indicator={indicator}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetRetweet({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n const indicator = useMemo(\n () => (\n <div className=\"flex items-center gap-2 text-sm\">\n <span>Retweeted by</span>\n {hasSource && (\n <Link\n className=\"text-sm\"\n underline=\"hover\"\n target=\"_blank\"\n href={twitterUserUrl(\n sourceTweet.user.screenName ?? sourceTweet.user.username,\n )}\n >\n @{sourceTweet.user.screenName ?? sourceTweet.user.username}\n </Link>\n )}\n </div>\n ),\n [hasSource, sourceTweet],\n );\n\n return (\n <TweetSource\n data={data}\n indicator={indicator}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React from \"react\";\nimport { Skeleton } from \"@liberfi.io/ui\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetOriginal } from \"./tweet-original\";\nimport { TweetQuote } from \"./tweet-quote\";\nimport { TweetReply } from \"./tweet-reply\";\nimport { TweetRetweet } from \"./tweet-retweet\";\n\ntype Props = {\n data?: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n embed?: boolean;\n children?: React.ReactNode;\n loading?: boolean;\n};\n\n// ------------------------------------------------------------\nexport function TweetItem({\n data,\n headerActions,\n footerActions,\n embed = false,\n children,\n loading = false,\n}: Props) {\n if (loading || !data) {\n return <TweetSkeleton embed={embed} />;\n }\n\n const tweetType = data.tweet.type;\n\n // Render appropriate component based on tweet type\n const renderTweetComponent = () => {\n const commonProps = {\n data,\n headerActions,\n footerActions,\n embed,\n children,\n };\n\n switch (tweetType) {\n case \"reply\":\n return <TweetReply {...commonProps} />;\n case \"retweet\":\n return <TweetRetweet {...commonProps} />;\n case \"quote\":\n return <TweetQuote {...commonProps} />;\n default: // \"original\"\n return <TweetOriginal {...commonProps} />;\n }\n };\n\n return <div className=\"w-full\">{renderTweetComponent()}</div>;\n}\n\n// ------------------------------------------------------------\nfunction TweetSkeleton({ embed = false }: { embed?: boolean }) {\n const containerClass = embed\n ? \"bg-default-50 rounded-lg p-3 w-full mx-auto\"\n : \"bg-default-100 rounded-lg p-3 w-full mx-auto\";\n\n return (\n <div className={[\"flex flex-col gap-2\", containerClass].join(\" \")}>\n {/* User Info Skeleton */}\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"w-10 h-10 rounded-full\" />\n <div className=\"flex flex-col gap-1 flex-1\">\n <Skeleton className=\"h-4 w-24\" />\n <Skeleton className=\"h-3 w-16\" />\n </div>\n <Skeleton className=\"h-3 w-12\" />\n </div>\n\n {/* Content Skeleton */}\n <div className=\"flex flex-col gap-2\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-4 w-1/2\" />\n </div>\n\n {/* Media Skeleton */}\n <Skeleton className=\"h-48 w-full rounded-lg\" />\n\n {/* Actions Skeleton */}\n <div className=\"flex justify-between items-center pt-2\">\n <div className=\"flex gap-4\">\n <Skeleton className=\"h-6 w-16\" />\n <Skeleton className=\"h-6 w-16\" />\n <Skeleton className=\"h-6 w-16\" />\n </div>\n <Skeleton className=\"h-6 w-20\" />\n </div>\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { Avatar, Badge, Button, Image } from \"@liberfi.io/ui\";\nimport { formatPercent, SafeBigNumber } from \"@liberfi.io/utils\";\nimport { MediaToken } from \"../../../../types\";\n\ntype Props = {\n token: MediaToken;\n};\n\nexport function TweetTokenButton({ token }: Props) {\n const color = new SafeBigNumber(token.priceChange ?? \"0\").isPositive()\n ? \"primary\"\n : \"danger\";\n\n return (\n <Button\n color={color}\n variant=\"flat\"\n size=\"sm\"\n radius=\"full\"\n startContent={<TweetTokenIcon token={token} />}\n >\n <span>{token.symbol}</span>\n <span>\n {token.priceChange\n ? formatPercent(Number(token.priceChange) / 100)\n : \"--\"}\n </span>\n </Button>\n );\n}\n\nexport function TweetTokenIcon({ token }: Props) {\n const ChainIcon = useMemo(() => {\n return (\n <Image className=\"w-full h-full\" src={token.image} alt={token.chain} />\n );\n }, [token.chain, token.image]);\n\n return (\n <Badge\n className=\"w-2.5 h-2.5 p-0 border\"\n size=\"sm\"\n content={ChainIcon}\n shape=\"circle\"\n placement=\"bottom-right\"\n >\n <Avatar className=\"w-5 h-5\" radius=\"full\" src={token.image} />\n </Badge>\n );\n}\n","import { useCallback } from \"react\";\nimport { TweetMedia } from \"../../types\";\nimport { TweetTokenButton } from \"./tweet/tools/tweet-token-button\";\n// import { TweetTradeButton } from \"./tweet/tools/tweet-trade-button\";\nimport { TweetItem } from \"./tweet/tweet-item\";\n\ntype TweetsProps = {\n data: Array<TweetMedia>;\n loading: boolean;\n setIsPaused: (paused: boolean) => void;\n customHeaderActions?: (item: TweetMedia) => React.ReactNode;\n customFooterActions?: (item: TweetMedia) => React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function Tweets({\n data,\n loading,\n setIsPaused,\n customHeaderActions,\n customFooterActions,\n}: TweetsProps) {\n const footerActions = useCallback(\n (item: TweetMedia) => (\n <div className=\"flex gap-2.5 justify-between\">\n {item.token && <TweetTokenButton token={item.token} />}\n {customFooterActions?.(item)}\n {/* {item.token && <TweetTradeButton token={item.token} />} */}\n </div>\n ),\n [customFooterActions],\n );\n\n return (\n <div\n className=\"flex flex-col gap-2.5\"\n onMouseEnter={() => setIsPaused(true)}\n onMouseLeave={() => setIsPaused(false)}\n >\n {data.map((item: TweetMedia) => (\n <TweetItem\n key={item.id}\n data={item}\n headerActions={customHeaderActions?.(item)}\n footerActions={footerActions(item)}\n loading={loading}\n />\n ))}\n </div>\n );\n}\n","import { Skeleton } from \"@liberfi.io/ui\";\n\n// ------------------------------------------------------------\nexport function TweetSkeleton() {\n return (\n <div className=\"flex flex-col gap-2 bg-default-100 rounded-lg p-3 w-full mx-auto\">\n {/* User Info Skeleton */}\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"w-10 h-10 rounded-full\" />\n <div className=\"flex flex-col gap-1 flex-1\">\n <Skeleton className=\"h-4 w-40 rounded-md\" />\n <Skeleton className=\"h-3 w-32 rounded-md\" />\n </div>\n </div>\n\n {/* Content Skeleton */}\n <div className=\"flex flex-col gap-2\">\n <Skeleton className=\"h-4 w-full rounded-md\" />\n <Skeleton className=\"h-4 w-3/4 rounded-md\" />\n <Skeleton className=\"h-4 w-1/2 rounded-md\" />\n </div>\n\n {/* Media Skeleton */}\n <Skeleton className=\"h-48 w-full rounded-lg\" />\n </div>\n );\n}\n\nexport function TweetSkeletonList({ count = 3 }: { count: number }) {\n return (\n <div className=\"flex flex-col gap-2\">\n {Array.from({ length: count }).map((_, index) => (\n <TweetSkeleton key={index} />\n ))}\n </div>\n );\n}\n","import { useCallback, useEffect, useState } from \"react\";\nimport { useMediaTrackRuntime } from \"../../hooks/useMediaTrackRuntime\";\nimport { TweetMedia } from \"../../types\";\n\nexport const useTweets = () => {\n const [medias, setMedias] = useState<Array<TweetMedia>>([]);\n const [loading, setLoading] = useState(true);\n const [isPaused, setIsPaused] = useState(false);\n\n const runtime = useMediaTrackRuntime();\n\n const handleMedia = useCallback(\n (media: TweetMedia) => {\n setMedias((prevMedias) => {\n const idx = prevMedias.findIndex((it) => it.id === media.id);\n let newMedias: Array<TweetMedia>;\n\n if (idx >= 0) {\n newMedias = prevMedias.map((item, index) =>\n index === idx ? media : item,\n );\n } else {\n if (isPaused) {\n return prevMedias;\n }\n newMedias = [media, ...prevMedias];\n }\n\n return newMedias.slice(0, 30);\n });\n setLoading(false);\n },\n [isPaused],\n );\n\n useEffect(() => {\n const subTweet = runtime.subscribe(\"x-monitor-basic\", handleMedia);\n const subTweetToken = runtime.subscribe(\"x-monitor-token\", handleMedia);\n return () => {\n subTweet.unsubscribe();\n subTweetToken.unsubscribe();\n };\n }, [runtime, handleMedia]);\n\n return { medias, loading, isPaused, setIsPaused };\n};\n","import { useEffect } from \"react\";\nimport { TweetMedia } from \"../../types\";\nimport { TweetSkeletonList } from \"./tweet/tweet-skeleton\";\nimport { useTweets } from \"./tweets.script\";\nimport { Tweets } from \"./tweets.ui\";\n\n// ------------------------------------------------------------\nexport type TweetsWidgetProps = {\n onPauseChange?: (paused: boolean) => void;\n customHeaderActions?: (item: TweetMedia) => React.ReactNode;\n customFooterActions?: (item: TweetMedia) => React.ReactNode;\n};\n\nexport function TweetsWidget({\n onPauseChange,\n customHeaderActions,\n customFooterActions,\n}: TweetsWidgetProps) {\n const { medias, loading, isPaused, setIsPaused } = useTweets();\n\n useEffect(() => {\n onPauseChange?.(isPaused);\n }, [isPaused, onPauseChange]);\n\n if (loading) {\n return <TweetSkeletonList count={3} />;\n }\n\n return (\n <Tweets\n data={medias}\n loading={loading}\n setIsPaused={setIsPaused}\n customHeaderActions={customHeaderActions}\n customFooterActions={customFooterActions}\n />\n );\n}\n","export type MediaTrackUnsubscribe = () => void;\n\nexport interface MediaTrackSubscription {\n unsubscribe: MediaTrackUnsubscribe;\n}\n\nexport interface MediaTrackRuntime<T = unknown> {\n readonly generation: number;\n connect(): void;\n disconnect(): void;\n setLocaleTransform(transform: ((payload: T) => T) | null): void;\n subscribe(channel: string, listener: (payload: T) => void): MediaTrackSubscription;\n publish(channel: string, payload: T): void;\n}\n\nexport function createMediaTrackRuntime<T = unknown>(): MediaTrackRuntime<T> {\n let generation = 0;\n let connected = false;\n let localeTransform: ((payload: T) => T) | null = null;\n const listeners = new Map<string, Set<(payload: T) => void>>();\n\n return {\n get generation() {\n return generation;\n },\n connect() {\n generation += 1;\n connected = true;\n },\n disconnect() {\n connected = false;\n },\n setLocaleTransform(transform) {\n localeTransform = transform;\n },\n subscribe(channel, listener) {\n let bucket = listeners.get(channel);\n if (!bucket) {\n bucket = new Set();\n listeners.set(channel, bucket);\n }\n bucket.add(listener);\n let unsubscribed = false;\n return {\n unsubscribe() {\n if (unsubscribed) return;\n unsubscribed = true;\n const current = listeners.get(channel);\n current?.delete(listener);\n if (current && current.size === 0) {\n listeners.delete(channel);\n }\n },\n };\n },\n publish(channel, payload) {\n if (!connected) return;\n const next = localeTransform ? localeTransform(payload) : payload;\n listeners.get(channel)?.forEach((listener) => listener(next));\n },\n };\n}\n","import { PropsWithChildren, useContext, useEffect, useMemo } from \"react\";\nimport { MediaTrackContext } from \"../context\";\nimport { MediaTrackRuntimeContext } from \"../context/MediaTrackRuntimeContext\";\nimport { createMediaTrackRuntime } from \"../runtime/media-track-runtime\";\nimport type { IMediaTrackClient, TweetMedia } from \"../types\";\n\nexport type MediaTrackProviderProps = PropsWithChildren<{\n client: IMediaTrackClient;\n}>;\n\nexport function MediaTrackProvider({\n client,\n children,\n}: MediaTrackProviderProps) {\n const runtime = useMemo(() => createMediaTrackRuntime<TweetMedia>(), []);\n\n return (\n <MediaTrackContext.Provider value={{ client }}>\n <MediaTrackRuntimeContext.Provider value={runtime}>\n <MediaTrackClientBridge client={client} />\n {children}\n </MediaTrackRuntimeContext.Provider>\n </MediaTrackContext.Provider>\n );\n}\n\nfunction MediaTrackClientBridge({ client }: { client: IMediaTrackClient }) {\n const runtime = useContext(MediaTrackRuntimeContext);\n useEffect(() => {\n if (!runtime) return;\n runtime.connect();\n const basic = client.subscribeTweetMedia({\n callback: (media) => runtime.publish(\"x-monitor-basic\", media),\n });\n const token = client.subscribeTweetMediaToken({\n callback: (media) => runtime.publish(\"x-monitor-token\", media),\n });\n return () => {\n basic.unsubscribe();\n token.unsubscribe();\n runtime.disconnect();\n };\n }, [client, runtime]);\n return null;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/tweets/tweet/media/media-image.tsx","../src/components/tweets/tweet/media/media-video.tsx","../src/components/tweets/tweet/media/medias.tsx","../src/components/tweets/tweet/user/user-avatar.tsx","../src/components/tweets/tweet/user/user-info.tsx","../src/context/MediaTrackContext.ts","../src/context/MediaTrackRuntimeContext.ts","../src/hooks/useMediaTrackContext.ts","../src/hooks/useMediaTrackClient.ts","../src/hooks/useGenerateTweetMediaMemeMutation.ts","../src/hooks/useMediaTrackRuntime.ts","../src/hooks/useTranslateTweetMediaQuery.ts","../src/utils/parseText.tsx","../src/components/tweets/tweet/tools/translate.tsx","../src/components/tweets/tweet/tools/text-expand.tsx","../src/components/tweets/tweet/content/index.tsx","../src/components/tweets/tweet/tweet-source.tsx","../src/components/tweets/tweet/tweet-original.tsx","../src/components/tweets/tweet/tweet-quote.tsx","../src/components/tweets/tweet/tweet-reply.tsx","../src/components/tweets/tweet/tweet-retweet.tsx","../src/components/tweets/tweet/tweet-item.tsx","../src/components/tweets/tweet/tools/tweet-token-button.tsx","../src/components/tweets/tweets.ui.tsx","../src/components/tweets/tweet/tweet-skeleton.tsx","../src/components/tweets/tweets.script.ts","../src/components/tweets/tweets.widget.tsx","../src/runtime/media-track-runtime.ts","../src/providers/MediaTrackProvider.tsx"],"names":["MediaImage","src","isLoaded","setTrue","useBoolean","jsx","Skeleton","MediaVideo","Medias","medias","tweetHref","images","media","videos","renderVideos","video","renderImages","image","Link","jsxs","UserAvatar","url","name","size","fallbackName","useMemo","Avatar","UserInfo","user","renderTimestamp","renderActions","twitterUserUrl","MediaTrackContext","createContext","MediaTrackRuntimeContext","useMediaTrackContext","context","useContext","useMediaTrackClient","client","useGenerateTweetMediaMemeMutation","options","useMutation","params","useMediaTrackRuntime","runtime","translateTweetMedia","targetLanguage","useTranslateTweetMediaMutation","parseText","text","urlRegex","hashtagRegex","symbolRegex","matches","match","matchIndex","a","b","parts","lastIndex","key","item","e","hashtagUrl","Translate","data","embed","isTranslate","toggle","t","i18n","useTranslation","isTranslating","translatedText","setTranslatedText","useState","handleTranslate","useCallback","parsedText","Fragment","TranslateIcon","cn","TextExpand","isExpanded","onToggleExpand","renderExpand","ChevronUpIcon","ChevronDownIcon","Content","content","onLoad","ref","useRef","parsedContent","useEffect","current","TweetSource","headerActions","footerActions","indicator","children","setIsExpanded","containerClass","tweet","age","useTickAge","twitterTweetUrl","formatAge","TweetOriginal","TweetQuote","hasSource","TweetReply","sourceTweet","TweetRetweet","TweetItem","loading","TweetSkeleton","tweetType","commonProps","TweetTokenButton","token","color","SafeBigNumber","Button","TweetTokenIcon","formatPercent","ChainIcon","Image","Badge","Tweets","setIsPaused","customHeaderActions","customFooterActions","TweetSkeletonList","count","_","index","useTweets","setMedias","setLoading","isPaused","handleMedia","prevMedias","idx","it","newMedias","subTweet","subTweetToken","TweetsWidget","onPauseChange","createMediaTrackRuntime","generation","connected","localeTransform","listeners","transform","channel","listener","bucket","unsubscribed","payload","next","MediaTrackProvider","MediaTrackClientBridge","basic"],"mappings":"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","file":"index.js","sourcesContent":["import { useBoolean } from \"@liberfi.io/hooks\";\nimport { Skeleton } from \"@liberfi.io/ui\";\n\ntype Props = {\n src: string;\n};\n\n// ------------------------------------------------------------\nexport function MediaImage({ src }: Props) {\n const [isLoaded, { setTrue }] = useBoolean(false);\n if (!src) return null;\n\n return (\n <Skeleton isLoaded={isLoaded} className=\"w-full h-auto\">\n <img\n src={src}\n className=\"w-full h-full object-cover aspect-video\"\n onLoad={() => {\n setTrue();\n }}\n />\n </Skeleton>\n );\n}\n","type Props = {\n src: string;\n};\n\n// ------------------------------------------------------------\nexport function MediaVideo({ src }: Props) {\n if (!src) return null;\n\n return (\n <div className=\"w-full h-full overflow-hidden rounded-md mt-2\">\n <iframe\n className=\"w-full h-full aspect-video\"\n src={src}\n allowFullScreen\n />\n </div>\n );\n}\n","import { Link } from \"@liberfi.io/ui\";\nimport { TweetContentMedia } from \"../../../../types\";\nimport { MediaImage } from \"./media-image\";\nimport { MediaVideo } from \"./media-video\";\n\ntype Props = {\n medias: Array<TweetContentMedia>;\n tweetHref: string;\n};\n\nexport function Medias({ medias, tweetHref }: Props) {\n const images = medias.filter((media) => media.type === \"image\");\n const videos = medias.filter((media) => media.type === \"video\");\n\n const renderVideos = () => {\n if (!videos.length) return null;\n return (\n <div className={`grid grid-cols-1 gap-[1px] overflow-hidden rounded-md`}>\n {videos.map((video) => (\n <MediaVideo key={video.url} src={video.url} />\n ))}\n </div>\n );\n };\n\n const renderImages = () => {\n if (!images.length) return null;\n return (\n <div className={`grid grid-cols-1 gap-[1px] overflow-hidden rounded-md`}>\n {images.map((image) => (\n <Link key={image.url} href={tweetHref} target=\"_blank\">\n <MediaImage src={image.url} />\n </Link>\n ))}\n </div>\n );\n };\n\n return (\n <div className=\"flex flex-col gap-2\">\n {renderVideos()}\n {renderImages()}\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { Avatar, Skeleton } from \"@liberfi.io/ui\";\n\ntype Props = {\n url?: string;\n name?: string;\n size?: number;\n};\n\nexport function UserAvatar({ url, name = \"\", size = 36 }: Props) {\n const fallbackName = useMemo(() => (name ? name.slice(0, 2) : \"N/A\"), [name]);\n\n return (\n <Skeleton\n className=\"flex rounded-full flex-shrink-0\"\n style={{ width: size, height: size }}\n isLoaded={!!url}\n >\n <Avatar\n size=\"md\"\n color=\"primary\"\n radius=\"full\"\n showFallback\n name={fallbackName}\n src={url}\n style={{ width: size, height: size }}\n />\n </Skeleton>\n );\n}\n","import React from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetUser } from \"../../../../types\";\nimport { UserAvatar } from \"./user-avatar\";\n\ntype Props = {\n user: TweetUser;\n renderTimestamp?: React.ReactNode;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function UserInfo({ user, renderTimestamp, renderActions }: Props) {\n return (\n <div className=\"flex items-center justify-between gap-1\">\n <div className=\"flex items-center gap-1\">\n <UserAvatar url={user.avatar} name={user.username} />\n <div className=\"flex flex-col gap-0.5\">\n <div className=\"flex flex-row items-baseline gap-1\">\n <span className=\"text-foreground font-semibold truncate leading-none\">\n {user.username}\n </span>\n {renderTimestamp}\n </div>\n <Link\n target=\"_blank\"\n underline=\"hover\"\n className=\"text-text-muted text-sm leading-none\"\n href={twitterUserUrl(user.screenName ?? user.username)}\n >\n @{user.screenName ?? user.username}\n </Link>\n </div>\n </div>\n {renderActions}\n </div>\n );\n}\n","import { createContext } from \"react\";\nimport { IMediaTrackClient } from \"../types\";\n\nexport interface MediaTrackContextValue {\n client: IMediaTrackClient;\n}\n\nexport const MediaTrackContext = createContext<MediaTrackContextValue>(\n {} as MediaTrackContextValue,\n);\n","import { createContext } from \"react\";\nimport type { TweetMedia } from \"../types\";\nimport type { MediaTrackRuntime } from \"../runtime/media-track-runtime\";\n\nexport const MediaTrackRuntimeContext =\n createContext<MediaTrackRuntime<TweetMedia> | null>(null);\n","import { useContext } from \"react\";\nimport { MediaTrackContext } from \"../context\";\n\nexport function useMediaTrackContext() {\n const context = useContext(MediaTrackContext);\n if (!context) {\n throw new Error(\n \"useMediaTrackContext must be used within a MediaTrackProvider\",\n );\n }\n return context;\n}\n","import { useMediaTrackContext } from \"./useMediaTrackContext\";\n\nexport function useMediaTrackClient() {\n const { client } = useMediaTrackContext();\n return client;\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport { GeneratedMemeInfo, TweetMedia } from \"../types\";\nimport { useMediaTrackClient } from \"./useMediaTrackClient\";\n\nexport function useGenerateTweetMediaMemeMutation(\n options: Omit<\n UseMutationOptions<GeneratedMemeInfo, Error, TweetMedia, string[]>,\n \"mutationFn\"\n > = {},\n) {\n const client = useMediaTrackClient();\n return useMutation({\n mutationFn: async (params: TweetMedia) => client.generateMeme(params),\n ...options,\n });\n}\n","import { useContext } from \"react\";\nimport { MediaTrackRuntimeContext } from \"../context/MediaTrackRuntimeContext\";\n\nexport function useMediaTrackRuntime() {\n const runtime = useContext(MediaTrackRuntimeContext);\n if (!runtime) {\n throw new Error(\n \"useMediaTrackRuntime must be used within a MediaTrackProvider\",\n );\n }\n return runtime;\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport { LocaleCode } from \"@liberfi.io/i18n\";\nimport { IMediaTrackClient, TweetMedia } from \"../types\";\nimport { useMediaTrackClient } from \"./useMediaTrackClient\";\n\nexport interface UseTranslateTweetMediaParams {\n media: TweetMedia;\n targetLanguage: LocaleCode;\n options?: {\n sourceLanguage?: LocaleCode;\n sourceTweet?: boolean;\n };\n}\n\nexport async function translateTweetMedia(\n client: IMediaTrackClient,\n { media, targetLanguage, options }: UseTranslateTweetMediaParams,\n) {\n return await client.translate(media, targetLanguage, options);\n}\n\nexport function useTranslateTweetMediaMutation(\n options: Omit<\n UseMutationOptions<string, Error, UseTranslateTweetMediaParams>,\n \"mutationFn\"\n > = {},\n) {\n const client = useMediaTrackClient();\n return useMutation({\n mutationFn: async (params: UseTranslateTweetMediaParams) =>\n translateTweetMedia(client, params),\n ...options,\n });\n}\n","interface MatchItem {\n index: number;\n length: number;\n text: string;\n type: \"url\" | \"hashtag\" | \"symbol\";\n}\n\nexport function parseText(text: string): (string | React.ReactElement)[] {\n const urlRegex = /(https?:\\/\\/[^\\s]+|www\\.[^\\s]+)/gi;\n const hashtagRegex = /#[\\w]+/g;\n const symbolRegex = /\\$[A-Za-z][A-Za-z0-9_]*/g;\n\n const matches: MatchItem[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = urlRegex.exec(text)) !== null) {\n matches.push({\n index: match.index,\n length: match[0].length,\n text: match[0],\n type: \"url\",\n });\n }\n\n while ((match = hashtagRegex.exec(text)) !== null) {\n const matchIndex = match.index;\n const overlaps = matches.some(\n (m) => matchIndex >= m.index && matchIndex < m.index + m.length,\n );\n if (!overlaps) {\n matches.push({\n index: matchIndex,\n length: match[0].length,\n text: match[0],\n type: \"hashtag\",\n });\n }\n }\n\n while ((match = symbolRegex.exec(text)) !== null) {\n const matchIndex = match.index;\n const overlaps = matches.some(\n (m) => matchIndex >= m.index && matchIndex < m.index + m.length,\n );\n if (!overlaps) {\n matches.push({\n index: matchIndex,\n length: match[0].length,\n text: match[0],\n type: \"symbol\",\n });\n }\n }\n\n matches.sort((a, b) => a.index - b.index);\n\n const parts: (string | React.ReactElement)[] = [];\n let lastIndex = 0;\n let key = 0;\n\n matches.forEach((item) => {\n if (item.index > lastIndex) {\n parts.push(text.slice(lastIndex, item.index));\n }\n\n if (item.type === \"url\") {\n const url = item.text.startsWith(\"http\")\n ? item.text\n : `https://${item.text}`;\n parts.push(\n <a\n key={key++}\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline\"\n onClick={(e) => e.stopPropagation()}\n >\n {item.text}\n </a>,\n );\n } else if (item.type === \"hashtag\") {\n const hashtag = item.text.slice(1); // 移除 #\n const hashtagUrl = `https://x.com/hashtag/${hashtag}`;\n parts.push(\n <a\n key={key++}\n href={hashtagUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline\"\n onClick={(e) => e.stopPropagation()}\n >\n {item.text}\n </a>,\n );\n } else if (item.type === \"symbol\") {\n parts.push(\n <span key={key++} className=\"text-primary\">\n {item.text}\n </span>,\n );\n }\n\n lastIndex = item.index + item.length;\n });\n\n if (lastIndex < text.length) {\n parts.push(text.slice(lastIndex));\n }\n\n return parts.length > 0 ? parts : [text];\n}\n","import React, { MouseEvent, useCallback, useState } from \"react\";\nimport { useBoolean } from \"@liberfi.io/hooks\";\nimport { LocaleCode, useTranslation } from \"@liberfi.io/i18n\";\nimport { cn, Skeleton, TranslateIcon } from \"@liberfi.io/ui\";\nimport { useTranslateTweetMediaMutation } from \"../../../../hooks\";\nimport { TweetMedia } from \"../../../../types\";\nimport { parseText } from \"../../../../utils\";\n\ntype Props = {\n data: TweetMedia;\n embed?: boolean;\n text: string;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function Translate({ data, embed, renderActions }: Props) {\n const [isTranslate, { toggle }] = useBoolean(false);\n\n const { t, i18n } = useTranslation();\n\n const { mutateAsync: translateTweetMedia, isPending: isTranslating } =\n useTranslateTweetMediaMutation();\n\n const [translatedText, setTranslatedText] = useState<\n (string | React.ReactElement)[] | null\n >(null);\n\n const handleTranslate = useCallback(\n async (e: MouseEvent<HTMLDivElement>) => {\n e.stopPropagation();\n toggle();\n if (!translatedText) {\n const text = await translateTweetMedia({\n media: data,\n targetLanguage: i18n.language as LocaleCode,\n options: {\n sourceTweet: embed,\n },\n });\n const parsedText = parseText(text);\n setTranslatedText(parsedText);\n }\n },\n [toggle, translateTweetMedia, data, i18n.language, translatedText, embed],\n );\n\n return (\n <>\n <div className=\"flex items-center gap-1 text-xs\">\n <div\n onClick={handleTranslate}\n className=\"flex items-center gap-0.5 cursor-pointer text-primary hover:text-foreground\"\n >\n <TranslateIcon width=\"14\" height=\"14\" />\n {isTranslate\n ? t(\"mediaTrack.tweets.translate.hide\")\n : t(\"mediaTrack.tweets.translate.show\")}\n </div>\n {renderActions}\n </div>\n <div\n className={cn(!isTranslate && \"hidden\")}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n {isTranslate && (\n <div className=\"bg-content2 rounded-md p-2 text-text-primary text-sm leading-5\">\n {translatedText}\n {isTranslating && <Skeleton className=\"w-full h-4 rounded-md\" />}\n </div>\n )}\n </div>\n </>\n );\n}\n","import { useTranslation } from \"@liberfi.io/i18n\";\nimport { ChevronDownIcon, ChevronUpIcon } from \"@liberfi.io/ui\";\n\ntype Props = {\n isExpanded?: boolean;\n onToggleExpand?: (expanded: boolean) => void;\n};\n\nexport function TextExpand({ isExpanded, onToggleExpand }: Props) {\n const { t } = useTranslation();\n const renderExpand = () => {\n if (isExpanded) {\n return (\n <>\n <ChevronUpIcon\n className=\"border border-current\"\n width=\"12\"\n height=\"12\"\n />\n {t(\"mediaTrack.tweets.collapse\")}\n </>\n );\n }\n\n return (\n <>\n <ChevronDownIcon\n className=\"border border-current\"\n width=\"12\"\n height=\"12\"\n />\n {t(\"mediaTrack.tweets.expand\")}\n </>\n );\n };\n\n if (isExpanded === undefined) return null;\n\n return (\n <div className=\"flex items-center gap-1\">\n <div className=\"w-px h-2.5 bg-line-300\" />\n <button\n onClick={(e) => {\n e.stopPropagation();\n onToggleExpand?.(!isExpanded);\n }}\n className=\"flex items-center text-text-muted hover:text-foreground text-xs\"\n >\n {renderExpand()}\n </button>\n </div>\n );\n}\n","import { useEffect, useMemo, useRef } from \"react\";\nimport { parseText } from \"../../../../utils\";\n\ntype Props = {\n content: string;\n isExpanded?: boolean;\n onLoad?: () => void;\n};\n\n// ------------------------------------------------------------\nexport function Content({ content, isExpanded = false, onLoad }: Props) {\n const ref = useRef<HTMLDivElement>(null);\n\n const parsedContent = useMemo(() => parseText(content), [content]);\n\n useEffect(() => {\n const current = ref.current;\n if (!onLoad || !current) return;\n if (current.scrollHeight > current.clientHeight) {\n onLoad?.();\n }\n }, [isExpanded, onLoad]);\n\n return (\n <div\n ref={ref}\n className={[\n \"text-text-primary text-sm leading-5\",\n !isExpanded ? \"line-clamp-3\" : \"\",\n ].join(\" \")}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n {parsedContent}\n </div>\n );\n}\n","import React, { useMemo, useState } from \"react\";\nimport { useTickAge } from \"@liberfi.io/hooks\";\nimport { cn } from \"@liberfi.io/ui\";\nimport { formatAge, twitterTweetUrl } from \"@liberfi.io/utils\";\nimport { Tweet, TweetMedia } from \"../../../types\";\nimport { Content } from \"./content\";\nimport { Medias } from \"./media\";\nimport { Translate, TextExpand } from \"./tools\";\nimport { UserInfo } from \"./user\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n embed?: boolean;\n indicator?: React.ReactNode;\n children?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetSource({\n data,\n headerActions,\n footerActions,\n embed = false,\n indicator,\n children,\n}: Props) {\n const [isExpanded, setIsExpanded] = useState<boolean | undefined>(undefined);\n\n const containerClass = useMemo(() => {\n return embed\n ? \"bg-default-50 rounded-lg p-3 w-full mx-auto\"\n : \"bg-default-100 hover:bg-default-200 rounded-lg p-3 w-full mx-auto\";\n }, [embed]);\n\n const tweet = useMemo(\n () => (embed ? data.sourceTweet! : data.tweet),\n [data, embed],\n );\n\n const age = useTickAge((tweet as Tweet).timestamp);\n\n return (\n <div\n className={cn(\"flex flex-col gap-1.5 cursor-pointer\", containerClass)}\n onClick={() => {\n window.open(twitterTweetUrl(tweet.tweetId), \"_blank\");\n }}\n >\n {/* -------- USER INFO -------- */}\n <UserInfo\n user={tweet.user}\n renderTimestamp={\n embed ? undefined : (\n <div className=\"text-xs text-primary\">{formatAge(age)}</div>\n )\n }\n renderActions={headerActions}\n />\n\n {/* -------- MESSAGE TYPE INDICATOR -------- */}\n {indicator}\n\n {/* -------- CONTENT -------- */}\n {tweet.content.text && (\n <Content\n content={tweet.content.text}\n isExpanded={isExpanded}\n onLoad={() => setIsExpanded(false)}\n />\n )}\n\n {/* -------- TOOLS -------- */}\n {tweet.content.text && (\n <Translate\n data={data}\n embed={embed}\n text={tweet.content.text}\n renderActions={\n <TextExpand\n isExpanded={isExpanded}\n onToggleExpand={setIsExpanded}\n />\n }\n />\n )}\n\n {/* -------- MEDIA -------- */}\n <div\n className={cn(\n (!tweet.content.medias || tweet.content.medias.length === 0) &&\n \"hidden\",\n )}\n >\n {tweet.content.medias && tweet.content.medias.length > 0 && (\n <Medias\n medias={tweet.content.medias}\n tweetHref={twitterTweetUrl(tweet.tweetId)}\n />\n )}\n </div>\n\n {/* -------- CHILDREN -------- */}\n {children}\n\n {/* -------- Custom ACTIONS -------- */}\n {footerActions}\n </div>\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetOriginal({ data, headerActions, footerActions }: Props) {\n return (\n <TweetSource\n data={data}\n headerActions={headerActions}\n footerActions={footerActions}\n />\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetQuote({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n return (\n <TweetSource\n data={data}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { useTranslation } from \"@liberfi.io/i18n\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetReply({ data, headerActions, footerActions }: Props) {\n const { t } = useTranslation();\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>{t(\"mediaTrack.replyingTo\")}</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, t],\n );\n\n return (\n <TweetSource\n data={data}\n indicator={indicator}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { useTranslation } from \"@liberfi.io/i18n\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetRetweet({ data, headerActions, footerActions }: Props) {\n const { t } = useTranslation();\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>{t(\"mediaTrack.retweetedBy\")}</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, t],\n );\n\n return (\n <TweetSource\n data={data}\n indicator={indicator}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React from \"react\";\nimport { Skeleton } from \"@liberfi.io/ui\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetOriginal } from \"./tweet-original\";\nimport { TweetQuote } from \"./tweet-quote\";\nimport { TweetReply } from \"./tweet-reply\";\nimport { TweetRetweet } from \"./tweet-retweet\";\n\ntype Props = {\n data?: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n embed?: boolean;\n children?: React.ReactNode;\n loading?: boolean;\n};\n\n// ------------------------------------------------------------\nexport function TweetItem({\n data,\n headerActions,\n footerActions,\n embed = false,\n children,\n loading = false,\n}: Props) {\n if (loading || !data) {\n return <TweetSkeleton embed={embed} />;\n }\n\n const tweetType = data.tweet.type;\n\n // Render appropriate component based on tweet type\n const renderTweetComponent = () => {\n const commonProps = {\n data,\n headerActions,\n footerActions,\n embed,\n children,\n };\n\n switch (tweetType) {\n case \"reply\":\n return <TweetReply {...commonProps} />;\n case \"retweet\":\n return <TweetRetweet {...commonProps} />;\n case \"quote\":\n return <TweetQuote {...commonProps} />;\n default: // \"original\"\n return <TweetOriginal {...commonProps} />;\n }\n };\n\n return <div className=\"w-full\">{renderTweetComponent()}</div>;\n}\n\n// ------------------------------------------------------------\nfunction TweetSkeleton({ embed = false }: { embed?: boolean }) {\n const containerClass = embed\n ? \"bg-default-50 rounded-lg p-3 w-full mx-auto\"\n : \"bg-default-100 rounded-lg p-3 w-full mx-auto\";\n\n return (\n <div className={[\"flex flex-col gap-2\", containerClass].join(\" \")}>\n {/* User Info Skeleton */}\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"w-10 h-10 rounded-full\" />\n <div className=\"flex flex-col gap-1 flex-1\">\n <Skeleton className=\"h-4 w-24\" />\n <Skeleton className=\"h-3 w-16\" />\n </div>\n <Skeleton className=\"h-3 w-12\" />\n </div>\n\n {/* Content Skeleton */}\n <div className=\"flex flex-col gap-2\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-4 w-1/2\" />\n </div>\n\n {/* Media Skeleton */}\n <Skeleton className=\"h-48 w-full rounded-lg\" />\n\n {/* Actions Skeleton */}\n <div className=\"flex justify-between items-center pt-2\">\n <div className=\"flex gap-4\">\n <Skeleton className=\"h-6 w-16\" />\n <Skeleton className=\"h-6 w-16\" />\n <Skeleton className=\"h-6 w-16\" />\n </div>\n <Skeleton className=\"h-6 w-20\" />\n </div>\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { Avatar, Badge, Button, Image } from \"@liberfi.io/ui\";\nimport { formatPercent, SafeBigNumber } from \"@liberfi.io/utils\";\nimport { MediaToken } from \"../../../../types\";\n\ntype Props = {\n token: MediaToken;\n};\n\nexport function TweetTokenButton({ token }: Props) {\n const color = new SafeBigNumber(token.priceChange ?? \"0\").isPositive()\n ? \"primary\"\n : \"danger\";\n\n return (\n <Button\n color={color}\n variant=\"flat\"\n size=\"sm\"\n radius=\"full\"\n startContent={<TweetTokenIcon token={token} />}\n >\n <span>{token.symbol}</span>\n <span>\n {token.priceChange\n ? formatPercent(Number(token.priceChange) / 100)\n : \"--\"}\n </span>\n </Button>\n );\n}\n\nexport function TweetTokenIcon({ token }: Props) {\n const ChainIcon = useMemo(() => {\n return (\n <Image className=\"w-full h-full\" src={token.image} alt={token.chain} />\n );\n }, [token.chain, token.image]);\n\n return (\n <Badge\n className=\"w-2.5 h-2.5 p-0 border\"\n size=\"sm\"\n content={ChainIcon}\n shape=\"circle\"\n placement=\"bottom-right\"\n >\n <Avatar className=\"w-5 h-5\" radius=\"full\" src={token.image} />\n </Badge>\n );\n}\n","import { useCallback } from \"react\";\nimport { TweetMedia } from \"../../types\";\nimport { TweetTokenButton } from \"./tweet/tools/tweet-token-button\";\n// import { TweetTradeButton } from \"./tweet/tools/tweet-trade-button\";\nimport { TweetItem } from \"./tweet/tweet-item\";\n\ntype TweetsProps = {\n data: Array<TweetMedia>;\n loading: boolean;\n setIsPaused: (paused: boolean) => void;\n customHeaderActions?: (item: TweetMedia) => React.ReactNode;\n customFooterActions?: (item: TweetMedia) => React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function Tweets({\n data,\n loading,\n setIsPaused,\n customHeaderActions,\n customFooterActions,\n}: TweetsProps) {\n const footerActions = useCallback(\n (item: TweetMedia) => (\n <div className=\"flex gap-2.5 justify-between\">\n {item.token && <TweetTokenButton token={item.token} />}\n {customFooterActions?.(item)}\n {/* {item.token && <TweetTradeButton token={item.token} />} */}\n </div>\n ),\n [customFooterActions],\n );\n\n return (\n <div\n className=\"flex flex-col gap-2.5\"\n onMouseEnter={() => setIsPaused(true)}\n onMouseLeave={() => setIsPaused(false)}\n >\n {data.map((item: TweetMedia) => (\n <TweetItem\n key={item.id}\n data={item}\n headerActions={customHeaderActions?.(item)}\n footerActions={footerActions(item)}\n loading={loading}\n />\n ))}\n </div>\n );\n}\n","import { Skeleton } from \"@liberfi.io/ui\";\n\n// ------------------------------------------------------------\nexport function TweetSkeleton() {\n return (\n <div className=\"flex flex-col gap-2 bg-default-100 rounded-lg p-3 w-full mx-auto\">\n {/* User Info Skeleton */}\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"w-10 h-10 rounded-full\" />\n <div className=\"flex flex-col gap-1 flex-1\">\n <Skeleton className=\"h-4 w-40 rounded-md\" />\n <Skeleton className=\"h-3 w-32 rounded-md\" />\n </div>\n </div>\n\n {/* Content Skeleton */}\n <div className=\"flex flex-col gap-2\">\n <Skeleton className=\"h-4 w-full rounded-md\" />\n <Skeleton className=\"h-4 w-3/4 rounded-md\" />\n <Skeleton className=\"h-4 w-1/2 rounded-md\" />\n </div>\n\n {/* Media Skeleton */}\n <Skeleton className=\"h-48 w-full rounded-lg\" />\n </div>\n );\n}\n\nexport function TweetSkeletonList({ count = 3 }: { count: number }) {\n return (\n <div className=\"flex flex-col gap-2\">\n {Array.from({ length: count }).map((_, index) => (\n <TweetSkeleton key={index} />\n ))}\n </div>\n );\n}\n","import { useCallback, useEffect, useState } from \"react\";\nimport { useMediaTrackRuntime } from \"../../hooks/useMediaTrackRuntime\";\nimport { TweetMedia } from \"../../types\";\n\nexport const useTweets = () => {\n const [medias, setMedias] = useState<Array<TweetMedia>>([]);\n const [loading, setLoading] = useState(true);\n const [isPaused, setIsPaused] = useState(false);\n\n const runtime = useMediaTrackRuntime();\n\n const handleMedia = useCallback(\n (media: TweetMedia) => {\n setMedias((prevMedias) => {\n const idx = prevMedias.findIndex((it) => it.id === media.id);\n let newMedias: Array<TweetMedia>;\n\n if (idx >= 0) {\n newMedias = prevMedias.map((item, index) =>\n index === idx ? media : item,\n );\n } else {\n if (isPaused) {\n return prevMedias;\n }\n newMedias = [media, ...prevMedias];\n }\n\n return newMedias.slice(0, 30);\n });\n setLoading(false);\n },\n [isPaused],\n );\n\n useEffect(() => {\n const subTweet = runtime.subscribe(\"x-monitor-basic\", handleMedia);\n const subTweetToken = runtime.subscribe(\"x-monitor-token\", handleMedia);\n return () => {\n subTweet.unsubscribe();\n subTweetToken.unsubscribe();\n };\n }, [runtime, handleMedia]);\n\n return { medias, loading, isPaused, setIsPaused };\n};\n","import { useEffect } from \"react\";\nimport { TweetMedia } from \"../../types\";\nimport { TweetSkeletonList } from \"./tweet/tweet-skeleton\";\nimport { useTweets } from \"./tweets.script\";\nimport { Tweets } from \"./tweets.ui\";\n\n// ------------------------------------------------------------\nexport type TweetsWidgetProps = {\n onPauseChange?: (paused: boolean) => void;\n customHeaderActions?: (item: TweetMedia) => React.ReactNode;\n customFooterActions?: (item: TweetMedia) => React.ReactNode;\n};\n\nexport function TweetsWidget({\n onPauseChange,\n customHeaderActions,\n customFooterActions,\n}: TweetsWidgetProps) {\n const { medias, loading, isPaused, setIsPaused } = useTweets();\n\n useEffect(() => {\n onPauseChange?.(isPaused);\n }, [isPaused, onPauseChange]);\n\n if (loading) {\n return <TweetSkeletonList count={3} />;\n }\n\n return (\n <Tweets\n data={medias}\n loading={loading}\n setIsPaused={setIsPaused}\n customHeaderActions={customHeaderActions}\n customFooterActions={customFooterActions}\n />\n );\n}\n","export type MediaTrackUnsubscribe = () => void;\n\nexport interface MediaTrackSubscription {\n unsubscribe: MediaTrackUnsubscribe;\n}\n\nexport interface MediaTrackRuntime<T = unknown> {\n readonly generation: number;\n connect(): void;\n disconnect(): void;\n setLocaleTransform(transform: ((payload: T) => T) | null): void;\n subscribe(channel: string, listener: (payload: T) => void): MediaTrackSubscription;\n publish(channel: string, payload: T): void;\n}\n\nexport function createMediaTrackRuntime<T = unknown>(): MediaTrackRuntime<T> {\n let generation = 0;\n let connected = false;\n let localeTransform: ((payload: T) => T) | null = null;\n const listeners = new Map<string, Set<(payload: T) => void>>();\n\n return {\n get generation() {\n return generation;\n },\n connect() {\n generation += 1;\n connected = true;\n },\n disconnect() {\n connected = false;\n },\n setLocaleTransform(transform) {\n localeTransform = transform;\n },\n subscribe(channel, listener) {\n let bucket = listeners.get(channel);\n if (!bucket) {\n bucket = new Set();\n listeners.set(channel, bucket);\n }\n bucket.add(listener);\n let unsubscribed = false;\n return {\n unsubscribe() {\n if (unsubscribed) return;\n unsubscribed = true;\n const current = listeners.get(channel);\n current?.delete(listener);\n if (current && current.size === 0) {\n listeners.delete(channel);\n }\n },\n };\n },\n publish(channel, payload) {\n if (!connected) return;\n const next = localeTransform ? localeTransform(payload) : payload;\n listeners.get(channel)?.forEach((listener) => listener(next));\n },\n };\n}\n","import { PropsWithChildren, useContext, useEffect, useMemo } from \"react\";\nimport { MediaTrackContext } from \"../context\";\nimport { MediaTrackRuntimeContext } from \"../context/MediaTrackRuntimeContext\";\nimport { createMediaTrackRuntime } from \"../runtime/media-track-runtime\";\nimport type { IMediaTrackClient, TweetMedia } from \"../types\";\n\nexport type MediaTrackProviderProps = PropsWithChildren<{\n client: IMediaTrackClient;\n}>;\n\nexport function MediaTrackProvider({\n client,\n children,\n}: MediaTrackProviderProps) {\n const runtime = useMemo(() => createMediaTrackRuntime<TweetMedia>(), []);\n\n return (\n <MediaTrackContext.Provider value={{ client }}>\n <MediaTrackRuntimeContext.Provider value={runtime}>\n <MediaTrackClientBridge client={client} />\n {children}\n </MediaTrackRuntimeContext.Provider>\n </MediaTrackContext.Provider>\n );\n}\n\nfunction MediaTrackClientBridge({ client }: { client: IMediaTrackClient }) {\n const runtime = useContext(MediaTrackRuntimeContext);\n useEffect(() => {\n if (!runtime) return;\n runtime.connect();\n const basic = client.subscribeTweetMedia({\n callback: (media) => runtime.publish(\"x-monitor-basic\", media),\n });\n const token = client.subscribeTweetMediaToken({\n callback: (media) => runtime.publish(\"x-monitor-token\", media),\n });\n return () => {\n basic.unsubscribe();\n token.unsubscribe();\n runtime.disconnect();\n };\n }, [client, runtime]);\n return null;\n}\n"]}
|
package/dist/index.mjs
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
import {useBoolean,useTickAge}from'@liberfi.io/hooks';import {Skeleton,Avatar,Link,TranslateIcon,cn,ChevronUpIcon,ChevronDownIcon,Button,Image,Badge}from'@liberfi.io/ui';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {twitterUserUrl,formatAge,twitterTweetUrl,SafeBigNumber,formatPercent}from'@liberfi.io/utils';import {createContext,useMemo,useContext,useState,useCallback,useEffect,useRef}from'react';import {useTranslation}from'@liberfi.io/i18n';import {useMutation}from'@tanstack/react-query';function S({src:e}){let[t,{setTrue:r}]=useBoolean(false);return e?jsx(Skeleton,{isLoaded:t,className:"w-full h-auto",children:jsx("img",{src:e,className:"w-full h-full object-cover aspect-video",onLoad:()=>{r();}})}):null}function E({src:e}){return e?jsx("div",{className:"w-full h-full overflow-hidden rounded-md mt-2",children:jsx("iframe",{className:"w-full h-full aspect-video",src:e,allowFullScreen:true})}):null}function L({medias:e,tweetHref:t}){let r=e.filter(i=>i.type==="image"),o=e.filter(i=>i.type==="video"),a=()=>o.length?jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:o.map(i=>jsx(E,{src:i.url},i.url))}):null,s=()=>r.length?jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:r.map(i=>jsx(Link,{href:t,target:"_blank",children:jsx(S,{src:i.url})},i.url))}):null;return jsxs("div",{className:"flex flex-col gap-2",children:[a(),s()]})}function U({url:e,name:t="",size:r=36}){let o=useMemo(()=>t?t.slice(0,2):"N/A",[t]);return jsx(Skeleton,{className:"flex rounded-full flex-shrink-0",style:{width:r,height:r},isLoaded:!!e,children:jsx(Avatar,{size:"md",color:"primary",radius:"full",showFallback:true,name:o,src:e,style:{width:r,height:r}})})}function B({user:e,renderTimestamp:t,renderActions:r}){return jsxs("div",{className:"flex items-center justify-between gap-1",children:[jsxs("div",{className:"flex items-center gap-1",children:[jsx(U,{url:e.avatar,name:e.username}),jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxs("div",{className:"flex flex-row items-baseline gap-1",children:[jsx("span",{className:"text-foreground font-semibold truncate leading-none",children:e.username}),t]}),jsxs(Link,{target:"_blank",underline:"hover",className:"text-default-500 text-sm leading-none",href:twitterUserUrl(e.screenName??e.username),children:["@",e.screenName??e.username]})]})]}),r]})}var N=createContext({});var h=createContext(null);function O(){let e=useContext(N);if(!e)throw new Error("useMediaTrackContext must be used within a MediaTrackProvider");return e}function y(){let{client:e}=O();return e}function Ue(e={}){let t=y();return useMutation({mutationFn:async r=>t.generateMeme(r),...e})}function H(){let e=useContext(h);if(!e)throw new Error("useMediaTrackRuntime must be used within a MediaTrackProvider");return e}async function se(e,{media:t,targetLanguage:r,options:o}){return await e.translate(t,r,o)}function _(e={}){let t=y();return useMutation({mutationFn:async r=>se(t,r),...e})}function R(e){let t=/(https?:\/\/[^\s]+|www\.[^\s]+)/gi,r=/#[\w]+/g,o=/\$[A-Za-z][A-Za-z0-9_]*/g,a=[],s;for(;(s=t.exec(e))!==null;)a.push({index:s.index,length:s[0].length,text:s[0],type:"url"});for(;(s=r.exec(e))!==null;){let n=s.index;a.some(m=>n>=m.index&&n<m.index+m.length)||a.push({index:n,length:s[0].length,text:s[0],type:"hashtag"});}for(;(s=o.exec(e))!==null;){let n=s.index;a.some(m=>n>=m.index&&n<m.index+m.length)||a.push({index:n,length:s[0].length,text:s[0],type:"symbol"});}a.sort((n,u)=>n.index-u.index);let i=[],d=0,c=0;return a.forEach(n=>{if(n.index>d&&i.push(e.slice(d,n.index)),n.type==="url"){let u=n.text.startsWith("http")?n.text:`https://${n.text}`;i.push(jsx("a",{href:u,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:m=>m.stopPropagation(),children:n.text},c++));}else if(n.type==="hashtag"){let m=`https://x.com/hashtag/${n.text.slice(1)}`;i.push(jsx("a",{href:m,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:T=>T.stopPropagation(),children:n.text},c++));}else n.type==="symbol"&&i.push(jsx("span",{className:"text-primary",children:n.text},c++));d=n.index+n.length;}),d<e.length&&i.push(e.slice(d)),i.length>0?i:[e]}function W({data:e,embed:t,renderActions:r}){let[o,{toggle:a}]=useBoolean(false),{t:s,i18n:i}=useTranslation(),{mutateAsync:d,isPending:c}=_(),[n,u]=useState(null),m=useCallback(async T=>{if(T.stopPropagation(),a(),!n){let I=await d({media:e,targetLanguage:i.language,options:{sourceTweet:t}}),Me=R(I);u(Me);}},[a,d,e,i.language,n,t]);return jsxs(Fragment,{children:[jsxs("div",{className:"flex items-center gap-1 text-xs",children:[jsxs("div",{onClick:m,className:"flex items-center gap-0.5 cursor-pointer text-primary hover:text-foreground",children:[jsx(TranslateIcon,{width:"14",height:"14"}),s(o?"mediaTrack.tweets.translate.hide":"mediaTrack.tweets.translate.show")]}),r]}),jsx("div",{className:cn(!o&&"hidden"),onClick:T=>{T.stopPropagation();},children:o&&jsxs("div",{className:"bg-content2 rounded-md p-2 text-default-900 text-sm leading-5",children:[n,c&&jsx(Skeleton,{className:"w-full h-4 rounded-md"})]})})]})}function z({isExpanded:e,onToggleExpand:t}){let{t:r}=useTranslation(),o=()=>e?jsxs(Fragment,{children:[jsx(ChevronUpIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",r("mediaTrack.tweets.collapse")]}):jsxs(Fragment,{children:[jsx(ChevronDownIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",r("mediaTrack.tweets.expand")]});return e===void 0?null:jsxs("div",{className:"flex items-center gap-1",children:[jsx("div",{className:"w-px h-2.5 bg-line-300"}),jsx("button",{onClick:a=>{a.stopPropagation(),t?.(!e);},className:"flex items-center text-default-500 hover:text-foreground text-xs",children:o()})]})}function de({content:e,isExpanded:t=false,onLoad:r}){let o=useRef(null),a=useMemo(()=>R(e),[e]);return useEffect(()=>{let s=o.current;!r||!s||s.scrollHeight>s.clientHeight&&r?.();},[t,r]),jsx("div",{ref:o,className:["text-default-900 text-sm leading-5",t?"":"line-clamp-3"].join(" "),onClick:s=>{s.stopPropagation();},children:a})}function p({data:e,headerActions:t,footerActions:r,embed:o=false,indicator:a,children:s}){let[i,d]=useState(void 0),c=useMemo(()=>o?"bg-default-50 rounded-lg p-3 w-full mx-auto":"bg-default-100 hover:bg-default-200 rounded-lg p-3 w-full mx-auto",[o]),n=useMemo(()=>o?e.sourceTweet:e.tweet,[e,o]),u=useTickAge(n.timestamp);return jsxs("div",{className:cn("flex flex-col gap-1.5 cursor-pointer",c),onClick:()=>{window.open(twitterTweetUrl(n.tweetId),"_blank");},children:[jsx(B,{user:n.user,renderTimestamp:o?void 0:jsx("div",{className:"text-xs text-primary",children:formatAge(u)}),renderActions:t}),a,n.content.text&&jsx(de,{content:n.content.text,isExpanded:i,onLoad:()=>d(false)}),n.content.text&&jsx(W,{data:e,embed:o,text:n.content.text,renderActions:jsx(z,{isExpanded:i,onToggleExpand:d})}),jsx("div",{className:cn((!n.content.medias||n.content.medias.length===0)&&"hidden"),children:n.content.medias&&n.content.medias.length>0&&jsx(L,{medias:n.content.medias,tweetHref:twitterTweetUrl(n.tweetId)})}),s,r]})}function D({data:e,headerActions:t,footerActions:r}){return jsx(p,{data:e,headerActions:t,footerActions:r})}function Q({data:e,headerActions:t,footerActions:r}){let a=!!e.sourceTweet;return jsx(p,{data:e,headerActions:t,footerActions:r,children:a?jsx(p,{data:e,embed:true}):null})}function Z({data:e,headerActions:t,footerActions:r}){let o=e.sourceTweet,a=!!o,s=useMemo(()=>jsxs("div",{className:"flex items-center gap-2 text-sm",children:[jsx("span",{children:"Replying to"}),a&&jsxs(Link,{className:"text-sm",underline:"hover",target:"_blank",href:twitterUserUrl(o.user.screenName??o.user.username),children:["@",o.user.screenName??o.user.username]})]}),[a,o]);return jsx(p,{data:e,indicator:s,headerActions:t,footerActions:r,children:a?jsx(p,{data:e,embed:true}):null})}function J({data:e,headerActions:t,footerActions:r}){let o=e.sourceTweet,a=!!o,s=useMemo(()=>jsxs("div",{className:"flex items-center gap-2 text-sm",children:[jsx("span",{children:"Retweeted by"}),a&&jsxs(Link,{className:"text-sm",underline:"hover",target:"_blank",href:twitterUserUrl(o.user.screenName??o.user.username),children:["@",o.user.screenName??o.user.username]})]}),[a,o]);return jsx(p,{data:e,indicator:s,headerActions:t,footerActions:r,children:a?jsx(p,{data:e,embed:true}):null})}function K({data:e,headerActions:t,footerActions:r,embed:o=false,children:a,loading:s=false}){if(s||!e)return jsx(dt,{embed:o});let i=e.tweet.type;return jsx("div",{className:"w-full",children:(()=>{let c={data:e,headerActions:t,footerActions:r,embed:o,children:a};switch(i){case "reply":return jsx(Z,{...c});case "retweet":return jsx(J,{...c});case "quote":return jsx(Q,{...c});default:return jsx(D,{...c})}})()})}function dt({embed:e=false}){return jsxs("div",{className:["flex flex-col gap-2",e?"bg-default-50 rounded-lg p-3 w-full mx-auto":"bg-default-100 rounded-lg p-3 w-full mx-auto"].join(" "),children:[jsxs("div",{className:"flex items-center gap-3",children:[jsx(Skeleton,{className:"w-10 h-10 rounded-full"}),jsxs("div",{className:"flex flex-col gap-1 flex-1",children:[jsx(Skeleton,{className:"h-4 w-24"}),jsx(Skeleton,{className:"h-3 w-16"})]}),jsx(Skeleton,{className:"h-3 w-12"})]}),jsxs("div",{className:"flex flex-col gap-2",children:[jsx(Skeleton,{className:"h-4 w-full"}),jsx(Skeleton,{className:"h-4 w-3/4"}),jsx(Skeleton,{className:"h-4 w-1/2"})]}),jsx(Skeleton,{className:"h-48 w-full rounded-lg"}),jsxs("div",{className:"flex justify-between items-center pt-2",children:[jsxs("div",{className:"flex gap-4",children:[jsx(Skeleton,{className:"h-6 w-16"}),jsx(Skeleton,{className:"h-6 w-16"}),jsx(Skeleton,{className:"h-6 w-16"})]}),jsx(Skeleton,{className:"h-6 w-20"})]})]})}function xe({token:e}){let t=new SafeBigNumber(e.priceChange??"0").isPositive()?"primary":"danger";return jsxs(Button,{color:t,variant:"flat",size:"sm",radius:"full",startContent:jsx(wt,{token:e}),children:[jsx("span",{children:e.symbol}),jsx("span",{children:e.priceChange?formatPercent(Number(e.priceChange)/100):"--"})]})}function wt({token:e}){let t=useMemo(()=>jsx(Image,{className:"w-full h-full",src:e.image,alt:e.chain}),[e.chain,e.image]);return jsx(Badge,{className:"w-2.5 h-2.5 p-0 border",size:"sm",content:t,shape:"circle",placement:"bottom-right",children:jsx(Avatar,{className:"w-5 h-5",radius:"full",src:e.image})})}function Y({data:e,loading:t,setIsPaused:r,customHeaderActions:o,customFooterActions:a}){let s=useCallback(i=>jsxs("div",{className:"flex gap-2.5 justify-between",children:[i.token&&jsx(xe,{token:i.token}),a?.(i)]}),[a]);return jsx("div",{className:"flex flex-col gap-2.5",onMouseEnter:()=>r(true),onMouseLeave:()=>r(false),children:e.map(i=>jsx(K,{data:i,headerActions:o?.(i),footerActions:s(i),loading:t},i.id))})}function we(){return jsxs("div",{className:"flex flex-col gap-2 bg-default-100 rounded-lg p-3 w-full mx-auto",children:[jsxs("div",{className:"flex items-center gap-3",children:[jsx(Skeleton,{className:"w-10 h-10 rounded-full"}),jsxs("div",{className:"flex flex-col gap-1 flex-1",children:[jsx(Skeleton,{className:"h-4 w-40 rounded-md"}),jsx(Skeleton,{className:"h-3 w-32 rounded-md"})]})]}),jsxs("div",{className:"flex flex-col gap-2",children:[jsx(Skeleton,{className:"h-4 w-full rounded-md"}),jsx(Skeleton,{className:"h-4 w-3/4 rounded-md"}),jsx(Skeleton,{className:"h-4 w-1/2 rounded-md"})]}),jsx(Skeleton,{className:"h-48 w-full rounded-lg"})]})}function j({count:e=3}){return jsx("div",{className:"flex flex-col gap-2",children:Array.from({length:e}).map((t,r)=>jsx(we,{},r))})}var te=()=>{let[e,t]=useState([]),[r,o]=useState(true),[a,s]=useState(false),i=H(),d=useCallback(c=>{t(n=>{let u=n.findIndex(T=>T.id===c.id),m;if(u>=0)m=n.map((T,I)=>I===u?c:T);else {if(a)return n;m=[c,...n];}return m.slice(0,30)}),o(false);},[a]);return useEffect(()=>{let c=i.subscribe("x-monitor-basic",d),n=i.subscribe("x-monitor-token",d);return ()=>{c.unsubscribe(),n.unsubscribe();}},[i,d]),{medias:e,loading:r,isPaused:a,setIsPaused:s}};function Nt({onPauseChange:e,customHeaderActions:t,customFooterActions:r}){let{medias:o,loading:a,isPaused:s,setIsPaused:i}=te();return useEffect(()=>{e?.(s);},[s,e]),a?jsx(j,{count:3}):jsx(Y,{data:o,loading:a,setIsPaused:i,customHeaderActions:t,customFooterActions:r})}function re(){let e=0,t=false,r=null,o=new Map;return {get generation(){return e},connect(){e+=1,t=true;},disconnect(){t=false;},setLocaleTransform(a){r=a;},subscribe(a,s){let i=o.get(a);i||(i=new Set,o.set(a,i)),i.add(s);let d=false;return {unsubscribe(){if(d)return;d=true;let c=o.get(a);c?.delete(s),c&&c.size===0&&o.delete(a);}}},publish(a,s){if(!t)return;let i=r?r(s):s;o.get(a)?.forEach(d=>d(i));}}}function Pt({client:e,children:t}){let r=useMemo(()=>re(),[]);return jsx(N.Provider,{value:{client:e},children:jsxs(h.Provider,{value:r,children:[jsx(At,{client:e}),t]})})}function At({client:e}){let t=useContext(h);return useEffect(()=>{if(!t)return;t.connect();let r=e.subscribeTweetMedia({callback:a=>t.publish("x-monitor-basic",a)}),o=e.subscribeTweetMediaToken({callback:a=>t.publish("x-monitor-token",a)});return ()=>{r.unsubscribe(),o.unsubscribe(),t.disconnect();}},[e,t]),null}
|
|
2
|
-
export{S as MediaImage,N as MediaTrackContext,
|
|
1
|
+
import {useBoolean,useTickAge}from'@liberfi.io/hooks';import {Skeleton,Avatar,Link,TranslateIcon,cn,ChevronUpIcon,ChevronDownIcon,Button,Image,Badge}from'@liberfi.io/ui';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {twitterUserUrl,formatAge,twitterTweetUrl,SafeBigNumber,formatPercent}from'@liberfi.io/utils';import {createContext,useMemo,useContext,useState,useCallback,useEffect,useRef}from'react';import {useTranslation}from'@liberfi.io/i18n';import {useMutation}from'@tanstack/react-query';function S({src:e}){let[t,{setTrue:o}]=useBoolean(false);return e?jsx(Skeleton,{isLoaded:t,className:"w-full h-auto",children:jsx("img",{src:e,className:"w-full h-full object-cover aspect-video",onLoad:()=>{o();}})}):null}function E({src:e}){return e?jsx("div",{className:"w-full h-full overflow-hidden rounded-md mt-2",children:jsx("iframe",{className:"w-full h-full aspect-video",src:e,allowFullScreen:true})}):null}function L({medias:e,tweetHref:t}){let o=e.filter(a=>a.type==="image"),i=e.filter(a=>a.type==="video"),r=()=>i.length?jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:i.map(a=>jsx(E,{src:a.url},a.url))}):null,s=()=>o.length?jsx("div",{className:"grid grid-cols-1 gap-[1px] overflow-hidden rounded-md",children:o.map(a=>jsx(Link,{href:t,target:"_blank",children:jsx(S,{src:a.url})},a.url))}):null;return jsxs("div",{className:"flex flex-col gap-2",children:[r(),s()]})}function U({url:e,name:t="",size:o=36}){let i=useMemo(()=>t?t.slice(0,2):"N/A",[t]);return jsx(Skeleton,{className:"flex rounded-full flex-shrink-0",style:{width:o,height:o},isLoaded:!!e,children:jsx(Avatar,{size:"md",color:"primary",radius:"full",showFallback:true,name:i,src:e,style:{width:o,height:o}})})}function B({user:e,renderTimestamp:t,renderActions:o}){return jsxs("div",{className:"flex items-center justify-between gap-1",children:[jsxs("div",{className:"flex items-center gap-1",children:[jsx(U,{url:e.avatar,name:e.username}),jsxs("div",{className:"flex flex-col gap-0.5",children:[jsxs("div",{className:"flex flex-row items-baseline gap-1",children:[jsx("span",{className:"text-foreground font-semibold truncate leading-none",children:e.username}),t]}),jsxs(Link,{target:"_blank",underline:"hover",className:"text-text-muted text-sm leading-none",href:twitterUserUrl(e.screenName??e.username),children:["@",e.screenName??e.username]})]})]}),o]})}var N=createContext({});var h=createContext(null);function O(){let e=useContext(N);if(!e)throw new Error("useMediaTrackContext must be used within a MediaTrackProvider");return e}function y(){let{client:e}=O();return e}function Ue(e={}){let t=y();return useMutation({mutationFn:async o=>t.generateMeme(o),...e})}function H(){let e=useContext(h);if(!e)throw new Error("useMediaTrackRuntime must be used within a MediaTrackProvider");return e}async function se(e,{media:t,targetLanguage:o,options:i}){return await e.translate(t,o,i)}function _(e={}){let t=y();return useMutation({mutationFn:async o=>se(t,o),...e})}function R(e){let t=/(https?:\/\/[^\s]+|www\.[^\s]+)/gi,o=/#[\w]+/g,i=/\$[A-Za-z][A-Za-z0-9_]*/g,r=[],s;for(;(s=t.exec(e))!==null;)r.push({index:s.index,length:s[0].length,text:s[0],type:"url"});for(;(s=o.exec(e))!==null;){let n=s.index;r.some(m=>n>=m.index&&n<m.index+m.length)||r.push({index:n,length:s[0].length,text:s[0],type:"hashtag"});}for(;(s=i.exec(e))!==null;){let n=s.index;r.some(m=>n>=m.index&&n<m.index+m.length)||r.push({index:n,length:s[0].length,text:s[0],type:"symbol"});}r.sort((n,p)=>n.index-p.index);let a=[],d=0,c=0;return r.forEach(n=>{if(n.index>d&&a.push(e.slice(d,n.index)),n.type==="url"){let p=n.text.startsWith("http")?n.text:`https://${n.text}`;a.push(jsx("a",{href:p,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:m=>m.stopPropagation(),children:n.text},c++));}else if(n.type==="hashtag"){let m=`https://x.com/hashtag/${n.text.slice(1)}`;a.push(jsx("a",{href:m,target:"_blank",rel:"noopener noreferrer",className:"text-primary hover:underline",onClick:T=>T.stopPropagation(),children:n.text},c++));}else n.type==="symbol"&&a.push(jsx("span",{className:"text-primary",children:n.text},c++));d=n.index+n.length;}),d<e.length&&a.push(e.slice(d)),a.length>0?a:[e]}function W({data:e,embed:t,renderActions:o}){let[i,{toggle:r}]=useBoolean(false),{t:s,i18n:a}=useTranslation(),{mutateAsync:d,isPending:c}=_(),[n,p]=useState(null),m=useCallback(async T=>{if(T.stopPropagation(),r(),!n){let I=await d({media:e,targetLanguage:a.language,options:{sourceTweet:t}}),Me=R(I);p(Me);}},[r,d,e,a.language,n,t]);return jsxs(Fragment,{children:[jsxs("div",{className:"flex items-center gap-1 text-xs",children:[jsxs("div",{onClick:m,className:"flex items-center gap-0.5 cursor-pointer text-primary hover:text-foreground",children:[jsx(TranslateIcon,{width:"14",height:"14"}),s(i?"mediaTrack.tweets.translate.hide":"mediaTrack.tweets.translate.show")]}),o]}),jsx("div",{className:cn(!i&&"hidden"),onClick:T=>{T.stopPropagation();},children:i&&jsxs("div",{className:"bg-content2 rounded-md p-2 text-text-primary text-sm leading-5",children:[n,c&&jsx(Skeleton,{className:"w-full h-4 rounded-md"})]})})]})}function z({isExpanded:e,onToggleExpand:t}){let{t:o}=useTranslation(),i=()=>e?jsxs(Fragment,{children:[jsx(ChevronUpIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",o("mediaTrack.tweets.collapse")]}):jsxs(Fragment,{children:[jsx(ChevronDownIcon,{className:"border border-current",width:"12",height:"12"}),"\xA0",o("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:r=>{r.stopPropagation(),t?.(!e);},className:"flex items-center text-text-muted hover:text-foreground text-xs",children:i()})]})}function de({content:e,isExpanded:t=false,onLoad:o}){let i=useRef(null),r=useMemo(()=>R(e),[e]);return useEffect(()=>{let s=i.current;!o||!s||s.scrollHeight>s.clientHeight&&o?.();},[t,o]),jsx("div",{ref:i,className:["text-text-primary text-sm leading-5",t?"":"line-clamp-3"].join(" "),onClick:s=>{s.stopPropagation();},children:r})}function u({data:e,headerActions:t,footerActions:o,embed:i=false,indicator:r,children:s}){let[a,d]=useState(void 0),c=useMemo(()=>i?"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",[i]),n=useMemo(()=>i?e.sourceTweet:e.tweet,[e,i]),p=useTickAge(n.timestamp);return jsxs("div",{className:cn("flex flex-col gap-1.5 cursor-pointer",c),onClick:()=>{window.open(twitterTweetUrl(n.tweetId),"_blank");},children:[jsx(B,{user:n.user,renderTimestamp:i?void 0:jsx("div",{className:"text-xs text-primary",children:formatAge(p)}),renderActions:t}),r,n.content.text&&jsx(de,{content:n.content.text,isExpanded:a,onLoad:()=>d(false)}),n.content.text&&jsx(W,{data:e,embed:i,text:n.content.text,renderActions:jsx(z,{isExpanded:a,onToggleExpand:d})}),jsx("div",{className:cn((!n.content.medias||n.content.medias.length===0)&&"hidden"),children:n.content.medias&&n.content.medias.length>0&&jsx(L,{medias:n.content.medias,tweetHref:twitterTweetUrl(n.tweetId)})}),s,o]})}function D({data:e,headerActions:t,footerActions:o}){return jsx(u,{data:e,headerActions:t,footerActions:o})}function Q({data:e,headerActions:t,footerActions:o}){let r=!!e.sourceTweet;return jsx(u,{data:e,headerActions:t,footerActions:o,children:r?jsx(u,{data:e,embed:true}):null})}function Z({data:e,headerActions:t,footerActions:o}){let{t:i}=useTranslation(),r=e.sourceTweet,s=!!r,a=useMemo(()=>jsxs("div",{className:"flex items-center gap-2 text-sm",children:[jsx("span",{children:i("mediaTrack.replyingTo")}),s&&jsxs(Link,{className:"text-sm",underline:"hover",target:"_blank",href:twitterUserUrl(r.user.screenName??r.user.username),children:["@",r.user.screenName??r.user.username]})]}),[s,r,i]);return jsx(u,{data:e,indicator:a,headerActions:t,footerActions:o,children:s?jsx(u,{data:e,embed:true}):null})}function J({data:e,headerActions:t,footerActions:o}){let{t:i}=useTranslation(),r=e.sourceTweet,s=!!r,a=useMemo(()=>jsxs("div",{className:"flex items-center gap-2 text-sm",children:[jsx("span",{children:i("mediaTrack.retweetedBy")}),s&&jsxs(Link,{className:"text-sm",underline:"hover",target:"_blank",href:twitterUserUrl(r.user.screenName??r.user.username),children:["@",r.user.screenName??r.user.username]})]}),[s,r,i]);return jsx(u,{data:e,indicator:a,headerActions:t,footerActions:o,children:s?jsx(u,{data:e,embed:true}):null})}function K({data:e,headerActions:t,footerActions:o,embed:i=false,children:r,loading:s=false}){if(s||!e)return jsx(mt,{embed:i});let a=e.tweet.type;return jsx("div",{className:"w-full",children:(()=>{let c={data:e,headerActions:t,footerActions:o,embed:i,children:r};switch(a){case "reply":return jsx(Z,{...c});case "retweet":return jsx(J,{...c});case "quote":return jsx(Q,{...c});default:return jsx(D,{...c})}})()})}function mt({embed:e=false}){return jsxs("div",{className:["flex flex-col gap-2",e?"bg-default-50 rounded-lg p-3 w-full mx-auto":"bg-default-100 rounded-lg p-3 w-full mx-auto"].join(" "),children:[jsxs("div",{className:"flex items-center gap-3",children:[jsx(Skeleton,{className:"w-10 h-10 rounded-full"}),jsxs("div",{className:"flex flex-col gap-1 flex-1",children:[jsx(Skeleton,{className:"h-4 w-24"}),jsx(Skeleton,{className:"h-3 w-16"})]}),jsx(Skeleton,{className:"h-3 w-12"})]}),jsxs("div",{className:"flex flex-col gap-2",children:[jsx(Skeleton,{className:"h-4 w-full"}),jsx(Skeleton,{className:"h-4 w-3/4"}),jsx(Skeleton,{className:"h-4 w-1/2"})]}),jsx(Skeleton,{className:"h-48 w-full rounded-lg"}),jsxs("div",{className:"flex justify-between items-center pt-2",children:[jsxs("div",{className:"flex gap-4",children:[jsx(Skeleton,{className:"h-6 w-16"}),jsx(Skeleton,{className:"h-6 w-16"}),jsx(Skeleton,{className:"h-6 w-16"})]}),jsx(Skeleton,{className:"h-6 w-20"})]})]})}function xe({token:e}){let t=new SafeBigNumber(e.priceChange??"0").isPositive()?"primary":"danger";return jsxs(Button,{color:t,variant:"flat",size:"sm",radius:"full",startContent:jsx(ht,{token:e}),children:[jsx("span",{children:e.symbol}),jsx("span",{children:e.priceChange?formatPercent(Number(e.priceChange)/100):"--"})]})}function ht({token:e}){let t=useMemo(()=>jsx(Image,{className:"w-full h-full",src:e.image,alt:e.chain}),[e.chain,e.image]);return jsx(Badge,{className:"w-2.5 h-2.5 p-0 border",size:"sm",content:t,shape:"circle",placement:"bottom-right",children:jsx(Avatar,{className:"w-5 h-5",radius:"full",src:e.image})})}function Y({data:e,loading:t,setIsPaused:o,customHeaderActions:i,customFooterActions:r}){let s=useCallback(a=>jsxs("div",{className:"flex gap-2.5 justify-between",children:[a.token&&jsx(xe,{token:a.token}),r?.(a)]}),[r]);return jsx("div",{className:"flex flex-col gap-2.5",onMouseEnter:()=>o(true),onMouseLeave:()=>o(false),children:e.map(a=>jsx(K,{data:a,headerActions:i?.(a),footerActions:s(a),loading:t},a.id))})}function we(){return jsxs("div",{className:"flex flex-col gap-2 bg-default-100 rounded-lg p-3 w-full mx-auto",children:[jsxs("div",{className:"flex items-center gap-3",children:[jsx(Skeleton,{className:"w-10 h-10 rounded-full"}),jsxs("div",{className:"flex flex-col gap-1 flex-1",children:[jsx(Skeleton,{className:"h-4 w-40 rounded-md"}),jsx(Skeleton,{className:"h-3 w-32 rounded-md"})]})]}),jsxs("div",{className:"flex flex-col gap-2",children:[jsx(Skeleton,{className:"h-4 w-full rounded-md"}),jsx(Skeleton,{className:"h-4 w-3/4 rounded-md"}),jsx(Skeleton,{className:"h-4 w-1/2 rounded-md"})]}),jsx(Skeleton,{className:"h-48 w-full rounded-lg"})]})}function j({count:e=3}){return jsx("div",{className:"flex flex-col gap-2",children:Array.from({length:e}).map((t,o)=>jsx(we,{},o))})}var te=()=>{let[e,t]=useState([]),[o,i]=useState(true),[r,s]=useState(false),a=H(),d=useCallback(c=>{t(n=>{let p=n.findIndex(T=>T.id===c.id),m;if(p>=0)m=n.map((T,I)=>I===p?c:T);else {if(r)return n;m=[c,...n];}return m.slice(0,30)}),i(false);},[r]);return useEffect(()=>{let c=a.subscribe("x-monitor-basic",d),n=a.subscribe("x-monitor-token",d);return ()=>{c.unsubscribe(),n.unsubscribe();}},[a,d]),{medias:e,loading:o,isPaused:r,setIsPaused:s}};function Rt({onPauseChange:e,customHeaderActions:t,customFooterActions:o}){let{medias:i,loading:r,isPaused:s,setIsPaused:a}=te();return useEffect(()=>{e?.(s);},[s,e]),r?jsx(j,{count:3}):jsx(Y,{data:i,loading:r,setIsPaused:a,customHeaderActions:t,customFooterActions:o})}function re(){let e=0,t=false,o=null,i=new Map;return {get generation(){return e},connect(){e+=1,t=true;},disconnect(){t=false;},setLocaleTransform(r){o=r;},subscribe(r,s){let a=i.get(r);a||(a=new Set,i.set(r,a)),a.add(s);let d=false;return {unsubscribe(){if(d)return;d=true;let c=i.get(r);c?.delete(s),c&&c.size===0&&i.delete(r);}}},publish(r,s){if(!t)return;let a=o?o(s):s;i.get(r)?.forEach(d=>d(a));}}}function It({client:e,children:t}){let o=useMemo(()=>re(),[]);return jsx(N.Provider,{value:{client:e},children:jsxs(h.Provider,{value:o,children:[jsx(St,{client:e}),t]})})}function St({client:e}){let t=useContext(h);return useEffect(()=>{if(!t)return;t.connect();let o=e.subscribeTweetMedia({callback:r=>t.publish("x-monitor-basic",r)}),i=e.subscribeTweetMediaToken({callback:r=>t.publish("x-monitor-token",r)});return ()=>{o.unsubscribe(),i.unsubscribe(),t.disconnect();}},[e,t]),null}
|
|
2
|
+
export{S as MediaImage,N as MediaTrackContext,It as MediaTrackProvider,h as MediaTrackRuntimeContext,E as MediaVideo,L as Medias,z as TextExpand,W as Translate,K as TweetItem,D as TweetOriginal,Q as TweetQuote,Z as TweetReply,J as TweetRetweet,we as TweetSkeleton,j as TweetSkeletonList,u as TweetSource,Y as Tweets,Rt as TweetsWidget,U as UserAvatar,B as UserInfo,re as createMediaTrackRuntime,se as translateTweetMedia,Ue as useGenerateTweetMediaMemeMutation,y as useMediaTrackClient,O as useMediaTrackContext,H as useMediaTrackRuntime,_ as useTranslateTweetMediaMutation,te as useTweets};//# sourceMappingURL=index.mjs.map
|
|
3
3
|
//# sourceMappingURL=index.mjs.map
|
package/dist/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/components/tweets/tweet/media/media-image.tsx","../src/components/tweets/tweet/media/media-video.tsx","../src/components/tweets/tweet/media/medias.tsx","../src/components/tweets/tweet/user/user-avatar.tsx","../src/components/tweets/tweet/user/user-info.tsx","../src/context/MediaTrackContext.ts","../src/context/MediaTrackRuntimeContext.ts","../src/hooks/useMediaTrackContext.ts","../src/hooks/useMediaTrackClient.ts","../src/hooks/useGenerateTweetMediaMemeMutation.ts","../src/hooks/useMediaTrackRuntime.ts","../src/hooks/useTranslateTweetMediaQuery.ts","../src/utils/parseText.tsx","../src/components/tweets/tweet/tools/translate.tsx","../src/components/tweets/tweet/tools/text-expand.tsx","../src/components/tweets/tweet/content/index.tsx","../src/components/tweets/tweet/tweet-source.tsx","../src/components/tweets/tweet/tweet-original.tsx","../src/components/tweets/tweet/tweet-quote.tsx","../src/components/tweets/tweet/tweet-reply.tsx","../src/components/tweets/tweet/tweet-retweet.tsx","../src/components/tweets/tweet/tweet-item.tsx","../src/components/tweets/tweet/tools/tweet-token-button.tsx","../src/components/tweets/tweets.ui.tsx","../src/components/tweets/tweet/tweet-skeleton.tsx","../src/components/tweets/tweets.script.ts","../src/components/tweets/tweets.widget.tsx","../src/runtime/media-track-runtime.ts","../src/providers/MediaTrackProvider.tsx"],"names":["MediaImage","src","isLoaded","setTrue","useBoolean","jsx","Skeleton","MediaVideo","Medias","medias","tweetHref","images","media","videos","renderVideos","video","renderImages","image","Link","jsxs","UserAvatar","url","name","size","fallbackName","useMemo","Avatar","UserInfo","user","renderTimestamp","renderActions","twitterUserUrl","MediaTrackContext","createContext","MediaTrackRuntimeContext","useMediaTrackContext","context","useContext","useMediaTrackClient","client","useGenerateTweetMediaMemeMutation","options","useMutation","params","useMediaTrackRuntime","runtime","translateTweetMedia","targetLanguage","useTranslateTweetMediaMutation","parseText","text","urlRegex","hashtagRegex","symbolRegex","matches","match","matchIndex","a","b","parts","lastIndex","key","item","e","hashtagUrl","Translate","data","embed","isTranslate","toggle","t","i18n","useTranslation","isTranslating","translatedText","setTranslatedText","useState","handleTranslate","useCallback","parsedText","Fragment","TranslateIcon","cn","TextExpand","isExpanded","onToggleExpand","renderExpand","ChevronUpIcon","ChevronDownIcon","Content","content","onLoad","ref","useRef","parsedContent","useEffect","current","TweetSource","headerActions","footerActions","indicator","children","setIsExpanded","containerClass","tweet","age","useTickAge","twitterTweetUrl","formatAge","TweetOriginal","TweetQuote","hasSource","TweetReply","sourceTweet","TweetRetweet","TweetItem","loading","TweetSkeleton","tweetType","commonProps","TweetTokenButton","token","color","SafeBigNumber","Button","TweetTokenIcon","formatPercent","ChainIcon","Image","Badge","Tweets","setIsPaused","customHeaderActions","customFooterActions","TweetSkeletonList","count","_","index","useTweets","setMedias","setLoading","isPaused","handleMedia","prevMedias","idx","it","newMedias","subTweet","subTweetToken","TweetsWidget","onPauseChange","createMediaTrackRuntime","generation","connected","localeTransform","listeners","transform","channel","listener","bucket","unsubscribed","payload","next","MediaTrackProvider","MediaTrackClientBridge","basic"],"mappings":"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","file":"index.mjs","sourcesContent":["import { useBoolean } from \"@liberfi.io/hooks\";\nimport { Skeleton } from \"@liberfi.io/ui\";\n\ntype Props = {\n src: string;\n};\n\n// ------------------------------------------------------------\nexport function MediaImage({ src }: Props) {\n const [isLoaded, { setTrue }] = useBoolean(false);\n if (!src) return null;\n\n return (\n <Skeleton isLoaded={isLoaded} className=\"w-full h-auto\">\n <img\n src={src}\n className=\"w-full h-full object-cover aspect-video\"\n onLoad={() => {\n setTrue();\n }}\n />\n </Skeleton>\n );\n}\n","type Props = {\n src: string;\n};\n\n// ------------------------------------------------------------\nexport function MediaVideo({ src }: Props) {\n if (!src) return null;\n\n return (\n <div className=\"w-full h-full overflow-hidden rounded-md mt-2\">\n <iframe\n className=\"w-full h-full aspect-video\"\n src={src}\n allowFullScreen\n />\n </div>\n );\n}\n","import { Link } from \"@liberfi.io/ui\";\nimport { TweetContentMedia } from \"../../../../types\";\nimport { MediaImage } from \"./media-image\";\nimport { MediaVideo } from \"./media-video\";\n\ntype Props = {\n medias: Array<TweetContentMedia>;\n tweetHref: string;\n};\n\nexport function Medias({ medias, tweetHref }: Props) {\n const images = medias.filter((media) => media.type === \"image\");\n const videos = medias.filter((media) => media.type === \"video\");\n\n const renderVideos = () => {\n if (!videos.length) return null;\n return (\n <div className={`grid grid-cols-1 gap-[1px] overflow-hidden rounded-md`}>\n {videos.map((video) => (\n <MediaVideo key={video.url} src={video.url} />\n ))}\n </div>\n );\n };\n\n const renderImages = () => {\n if (!images.length) return null;\n return (\n <div className={`grid grid-cols-1 gap-[1px] overflow-hidden rounded-md`}>\n {images.map((image) => (\n <Link key={image.url} href={tweetHref} target=\"_blank\">\n <MediaImage src={image.url} />\n </Link>\n ))}\n </div>\n );\n };\n\n return (\n <div className=\"flex flex-col gap-2\">\n {renderVideos()}\n {renderImages()}\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { Avatar, Skeleton } from \"@liberfi.io/ui\";\n\ntype Props = {\n url?: string;\n name?: string;\n size?: number;\n};\n\nexport function UserAvatar({ url, name = \"\", size = 36 }: Props) {\n const fallbackName = useMemo(() => (name ? name.slice(0, 2) : \"N/A\"), [name]);\n\n return (\n <Skeleton\n className=\"flex rounded-full flex-shrink-0\"\n style={{ width: size, height: size }}\n isLoaded={!!url}\n >\n <Avatar\n size=\"md\"\n color=\"primary\"\n radius=\"full\"\n showFallback\n name={fallbackName}\n src={url}\n style={{ width: size, height: size }}\n />\n </Skeleton>\n );\n}\n","import React from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetUser } from \"../../../../types\";\nimport { UserAvatar } from \"./user-avatar\";\n\ntype Props = {\n user: TweetUser;\n renderTimestamp?: React.ReactNode;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function UserInfo({ user, renderTimestamp, renderActions }: Props) {\n return (\n <div className=\"flex items-center justify-between gap-1\">\n <div className=\"flex items-center gap-1\">\n <UserAvatar url={user.avatar} name={user.username} />\n <div className=\"flex flex-col gap-0.5\">\n <div className=\"flex flex-row items-baseline gap-1\">\n <span className=\"text-foreground font-semibold truncate leading-none\">\n {user.username}\n </span>\n {renderTimestamp}\n </div>\n <Link\n target=\"_blank\"\n underline=\"hover\"\n className=\"text-default-500 text-sm leading-none\"\n href={twitterUserUrl(user.screenName ?? user.username)}\n >\n @{user.screenName ?? user.username}\n </Link>\n </div>\n </div>\n {renderActions}\n </div>\n );\n}\n","import { createContext } from \"react\";\nimport { IMediaTrackClient } from \"../types\";\n\nexport interface MediaTrackContextValue {\n client: IMediaTrackClient;\n}\n\nexport const MediaTrackContext = createContext<MediaTrackContextValue>(\n {} as MediaTrackContextValue,\n);\n","import { createContext } from \"react\";\nimport type { TweetMedia } from \"../types\";\nimport type { MediaTrackRuntime } from \"../runtime/media-track-runtime\";\n\nexport const MediaTrackRuntimeContext =\n createContext<MediaTrackRuntime<TweetMedia> | null>(null);\n","import { useContext } from \"react\";\nimport { MediaTrackContext } from \"../context\";\n\nexport function useMediaTrackContext() {\n const context = useContext(MediaTrackContext);\n if (!context) {\n throw new Error(\n \"useMediaTrackContext must be used within a MediaTrackProvider\",\n );\n }\n return context;\n}\n","import { useMediaTrackContext } from \"./useMediaTrackContext\";\n\nexport function useMediaTrackClient() {\n const { client } = useMediaTrackContext();\n return client;\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport { GeneratedMemeInfo, TweetMedia } from \"../types\";\nimport { useMediaTrackClient } from \"./useMediaTrackClient\";\n\nexport function useGenerateTweetMediaMemeMutation(\n options: Omit<\n UseMutationOptions<GeneratedMemeInfo, Error, TweetMedia, string[]>,\n \"mutationFn\"\n > = {},\n) {\n const client = useMediaTrackClient();\n return useMutation({\n mutationFn: async (params: TweetMedia) => client.generateMeme(params),\n ...options,\n });\n}\n","import { useContext } from \"react\";\nimport { MediaTrackRuntimeContext } from \"../context/MediaTrackRuntimeContext\";\n\nexport function useMediaTrackRuntime() {\n const runtime = useContext(MediaTrackRuntimeContext);\n if (!runtime) {\n throw new Error(\n \"useMediaTrackRuntime must be used within a MediaTrackProvider\",\n );\n }\n return runtime;\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport { LocaleCode } from \"@liberfi.io/i18n\";\nimport { IMediaTrackClient, TweetMedia } from \"../types\";\nimport { useMediaTrackClient } from \"./useMediaTrackClient\";\n\nexport interface UseTranslateTweetMediaParams {\n media: TweetMedia;\n targetLanguage: LocaleCode;\n options?: {\n sourceLanguage?: LocaleCode;\n sourceTweet?: boolean;\n };\n}\n\nexport async function translateTweetMedia(\n client: IMediaTrackClient,\n { media, targetLanguage, options }: UseTranslateTweetMediaParams,\n) {\n return await client.translate(media, targetLanguage, options);\n}\n\nexport function useTranslateTweetMediaMutation(\n options: Omit<\n UseMutationOptions<string, Error, UseTranslateTweetMediaParams>,\n \"mutationFn\"\n > = {},\n) {\n const client = useMediaTrackClient();\n return useMutation({\n mutationFn: async (params: UseTranslateTweetMediaParams) =>\n translateTweetMedia(client, params),\n ...options,\n });\n}\n","interface MatchItem {\n index: number;\n length: number;\n text: string;\n type: \"url\" | \"hashtag\" | \"symbol\";\n}\n\nexport function parseText(text: string): (string | React.ReactElement)[] {\n const urlRegex = /(https?:\\/\\/[^\\s]+|www\\.[^\\s]+)/gi;\n const hashtagRegex = /#[\\w]+/g;\n const symbolRegex = /\\$[A-Za-z][A-Za-z0-9_]*/g;\n\n const matches: MatchItem[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = urlRegex.exec(text)) !== null) {\n matches.push({\n index: match.index,\n length: match[0].length,\n text: match[0],\n type: \"url\",\n });\n }\n\n while ((match = hashtagRegex.exec(text)) !== null) {\n const matchIndex = match.index;\n const overlaps = matches.some(\n (m) => matchIndex >= m.index && matchIndex < m.index + m.length,\n );\n if (!overlaps) {\n matches.push({\n index: matchIndex,\n length: match[0].length,\n text: match[0],\n type: \"hashtag\",\n });\n }\n }\n\n while ((match = symbolRegex.exec(text)) !== null) {\n const matchIndex = match.index;\n const overlaps = matches.some(\n (m) => matchIndex >= m.index && matchIndex < m.index + m.length,\n );\n if (!overlaps) {\n matches.push({\n index: matchIndex,\n length: match[0].length,\n text: match[0],\n type: \"symbol\",\n });\n }\n }\n\n matches.sort((a, b) => a.index - b.index);\n\n const parts: (string | React.ReactElement)[] = [];\n let lastIndex = 0;\n let key = 0;\n\n matches.forEach((item) => {\n if (item.index > lastIndex) {\n parts.push(text.slice(lastIndex, item.index));\n }\n\n if (item.type === \"url\") {\n const url = item.text.startsWith(\"http\")\n ? item.text\n : `https://${item.text}`;\n parts.push(\n <a\n key={key++}\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline\"\n onClick={(e) => e.stopPropagation()}\n >\n {item.text}\n </a>,\n );\n } else if (item.type === \"hashtag\") {\n const hashtag = item.text.slice(1); // 移除 #\n const hashtagUrl = `https://x.com/hashtag/${hashtag}`;\n parts.push(\n <a\n key={key++}\n href={hashtagUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline\"\n onClick={(e) => e.stopPropagation()}\n >\n {item.text}\n </a>,\n );\n } else if (item.type === \"symbol\") {\n parts.push(\n <span key={key++} className=\"text-primary\">\n {item.text}\n </span>,\n );\n }\n\n lastIndex = item.index + item.length;\n });\n\n if (lastIndex < text.length) {\n parts.push(text.slice(lastIndex));\n }\n\n return parts.length > 0 ? parts : [text];\n}\n","import React, { MouseEvent, useCallback, useState } from \"react\";\nimport { useBoolean } from \"@liberfi.io/hooks\";\nimport { LocaleCode, useTranslation } from \"@liberfi.io/i18n\";\nimport { cn, Skeleton, TranslateIcon } from \"@liberfi.io/ui\";\nimport { useTranslateTweetMediaMutation } from \"../../../../hooks\";\nimport { TweetMedia } from \"../../../../types\";\nimport { parseText } from \"../../../../utils\";\n\ntype Props = {\n data: TweetMedia;\n embed?: boolean;\n text: string;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function Translate({ data, embed, renderActions }: Props) {\n const [isTranslate, { toggle }] = useBoolean(false);\n\n const { t, i18n } = useTranslation();\n\n const { mutateAsync: translateTweetMedia, isPending: isTranslating } =\n useTranslateTweetMediaMutation();\n\n const [translatedText, setTranslatedText] = useState<\n (string | React.ReactElement)[] | null\n >(null);\n\n const handleTranslate = useCallback(\n async (e: MouseEvent<HTMLDivElement>) => {\n e.stopPropagation();\n toggle();\n if (!translatedText) {\n const text = await translateTweetMedia({\n media: data,\n targetLanguage: i18n.language as LocaleCode,\n options: {\n sourceTweet: embed,\n },\n });\n const parsedText = parseText(text);\n setTranslatedText(parsedText);\n }\n },\n [toggle, translateTweetMedia, data, i18n.language, translatedText, embed],\n );\n\n return (\n <>\n <div className=\"flex items-center gap-1 text-xs\">\n <div\n onClick={handleTranslate}\n className=\"flex items-center gap-0.5 cursor-pointer text-primary hover:text-foreground\"\n >\n <TranslateIcon width=\"14\" height=\"14\" />\n {isTranslate\n ? t(\"mediaTrack.tweets.translate.hide\")\n : t(\"mediaTrack.tweets.translate.show\")}\n </div>\n {renderActions}\n </div>\n <div\n className={cn(!isTranslate && \"hidden\")}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n {isTranslate && (\n <div className=\"bg-content2 rounded-md p-2 text-default-900 text-sm leading-5\">\n {translatedText}\n {isTranslating && <Skeleton className=\"w-full h-4 rounded-md\" />}\n </div>\n )}\n </div>\n </>\n );\n}\n","import { useTranslation } from \"@liberfi.io/i18n\";\nimport { ChevronDownIcon, ChevronUpIcon } from \"@liberfi.io/ui\";\n\ntype Props = {\n isExpanded?: boolean;\n onToggleExpand?: (expanded: boolean) => void;\n};\n\nexport function TextExpand({ isExpanded, onToggleExpand }: Props) {\n const { t } = useTranslation();\n const renderExpand = () => {\n if (isExpanded) {\n return (\n <>\n <ChevronUpIcon\n className=\"border border-current\"\n width=\"12\"\n height=\"12\"\n />\n {t(\"mediaTrack.tweets.collapse\")}\n </>\n );\n }\n\n return (\n <>\n <ChevronDownIcon\n className=\"border border-current\"\n width=\"12\"\n height=\"12\"\n />\n {t(\"mediaTrack.tweets.expand\")}\n </>\n );\n };\n\n if (isExpanded === undefined) return null;\n\n return (\n <div className=\"flex items-center gap-1\">\n <div className=\"w-px h-2.5 bg-line-300\" />\n <button\n onClick={(e) => {\n e.stopPropagation();\n onToggleExpand?.(!isExpanded);\n }}\n className=\"flex items-center text-default-500 hover:text-foreground text-xs\"\n >\n {renderExpand()}\n </button>\n </div>\n );\n}\n","import { useEffect, useMemo, useRef } from \"react\";\nimport { parseText } from \"../../../../utils\";\n\ntype Props = {\n content: string;\n isExpanded?: boolean;\n onLoad?: () => void;\n};\n\n// ------------------------------------------------------------\nexport function Content({ content, isExpanded = false, onLoad }: Props) {\n const ref = useRef<HTMLDivElement>(null);\n\n const parsedContent = useMemo(() => parseText(content), [content]);\n\n useEffect(() => {\n const current = ref.current;\n if (!onLoad || !current) return;\n if (current.scrollHeight > current.clientHeight) {\n onLoad?.();\n }\n }, [isExpanded, onLoad]);\n\n return (\n <div\n ref={ref}\n className={[\n \"text-default-900 text-sm leading-5\",\n !isExpanded ? \"line-clamp-3\" : \"\",\n ].join(\" \")}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n {parsedContent}\n </div>\n );\n}\n","import React, { useMemo, useState } from \"react\";\nimport { useTickAge } from \"@liberfi.io/hooks\";\nimport { cn } from \"@liberfi.io/ui\";\nimport { formatAge, twitterTweetUrl } from \"@liberfi.io/utils\";\nimport { Tweet, TweetMedia } from \"../../../types\";\nimport { Content } from \"./content\";\nimport { Medias } from \"./media\";\nimport { Translate, TextExpand } from \"./tools\";\nimport { UserInfo } from \"./user\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n embed?: boolean;\n indicator?: React.ReactNode;\n children?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetSource({\n data,\n headerActions,\n footerActions,\n embed = false,\n indicator,\n children,\n}: Props) {\n const [isExpanded, setIsExpanded] = useState<boolean | undefined>(undefined);\n\n const containerClass = useMemo(() => {\n return embed\n ? \"bg-default-50 rounded-lg p-3 w-full mx-auto\"\n : \"bg-default-100 hover:bg-default-200 rounded-lg p-3 w-full mx-auto\";\n }, [embed]);\n\n const tweet = useMemo(\n () => (embed ? data.sourceTweet! : data.tweet),\n [data, embed],\n );\n\n const age = useTickAge((tweet as Tweet).timestamp);\n\n return (\n <div\n className={cn(\"flex flex-col gap-1.5 cursor-pointer\", containerClass)}\n onClick={() => {\n window.open(twitterTweetUrl(tweet.tweetId), \"_blank\");\n }}\n >\n {/* -------- USER INFO -------- */}\n <UserInfo\n user={tweet.user}\n renderTimestamp={\n embed ? undefined : (\n <div className=\"text-xs text-primary\">{formatAge(age)}</div>\n )\n }\n renderActions={headerActions}\n />\n\n {/* -------- MESSAGE TYPE INDICATOR -------- */}\n {indicator}\n\n {/* -------- CONTENT -------- */}\n {tweet.content.text && (\n <Content\n content={tweet.content.text}\n isExpanded={isExpanded}\n onLoad={() => setIsExpanded(false)}\n />\n )}\n\n {/* -------- TOOLS -------- */}\n {tweet.content.text && (\n <Translate\n data={data}\n embed={embed}\n text={tweet.content.text}\n renderActions={\n <TextExpand\n isExpanded={isExpanded}\n onToggleExpand={setIsExpanded}\n />\n }\n />\n )}\n\n {/* -------- MEDIA -------- */}\n <div\n className={cn(\n (!tweet.content.medias || tweet.content.medias.length === 0) &&\n \"hidden\",\n )}\n >\n {tweet.content.medias && tweet.content.medias.length > 0 && (\n <Medias\n medias={tweet.content.medias}\n tweetHref={twitterTweetUrl(tweet.tweetId)}\n />\n )}\n </div>\n\n {/* -------- CHILDREN -------- */}\n {children}\n\n {/* -------- Custom ACTIONS -------- */}\n {footerActions}\n </div>\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetOriginal({ data, headerActions, footerActions }: Props) {\n return (\n <TweetSource\n data={data}\n headerActions={headerActions}\n footerActions={footerActions}\n />\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetQuote({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n return (\n <TweetSource\n data={data}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetReply({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n const indicator = useMemo(\n () => (\n <div className=\"flex items-center gap-2 text-sm\">\n <span>Replying to</span>\n {hasSource && (\n <Link\n className=\"text-sm\"\n underline=\"hover\"\n target=\"_blank\"\n href={twitterUserUrl(\n sourceTweet.user.screenName ?? sourceTweet.user.username,\n )}\n >\n @{sourceTweet.user.screenName ?? sourceTweet.user.username}\n </Link>\n )}\n </div>\n ),\n [hasSource, sourceTweet],\n );\n\n return (\n <TweetSource\n data={data}\n indicator={indicator}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetRetweet({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n const indicator = useMemo(\n () => (\n <div className=\"flex items-center gap-2 text-sm\">\n <span>Retweeted by</span>\n {hasSource && (\n <Link\n className=\"text-sm\"\n underline=\"hover\"\n target=\"_blank\"\n href={twitterUserUrl(\n sourceTweet.user.screenName ?? sourceTweet.user.username,\n )}\n >\n @{sourceTweet.user.screenName ?? sourceTweet.user.username}\n </Link>\n )}\n </div>\n ),\n [hasSource, sourceTweet],\n );\n\n return (\n <TweetSource\n data={data}\n indicator={indicator}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React from \"react\";\nimport { Skeleton } from \"@liberfi.io/ui\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetOriginal } from \"./tweet-original\";\nimport { TweetQuote } from \"./tweet-quote\";\nimport { TweetReply } from \"./tweet-reply\";\nimport { TweetRetweet } from \"./tweet-retweet\";\n\ntype Props = {\n data?: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n embed?: boolean;\n children?: React.ReactNode;\n loading?: boolean;\n};\n\n// ------------------------------------------------------------\nexport function TweetItem({\n data,\n headerActions,\n footerActions,\n embed = false,\n children,\n loading = false,\n}: Props) {\n if (loading || !data) {\n return <TweetSkeleton embed={embed} />;\n }\n\n const tweetType = data.tweet.type;\n\n // Render appropriate component based on tweet type\n const renderTweetComponent = () => {\n const commonProps = {\n data,\n headerActions,\n footerActions,\n embed,\n children,\n };\n\n switch (tweetType) {\n case \"reply\":\n return <TweetReply {...commonProps} />;\n case \"retweet\":\n return <TweetRetweet {...commonProps} />;\n case \"quote\":\n return <TweetQuote {...commonProps} />;\n default: // \"original\"\n return <TweetOriginal {...commonProps} />;\n }\n };\n\n return <div className=\"w-full\">{renderTweetComponent()}</div>;\n}\n\n// ------------------------------------------------------------\nfunction TweetSkeleton({ embed = false }: { embed?: boolean }) {\n const containerClass = embed\n ? \"bg-default-50 rounded-lg p-3 w-full mx-auto\"\n : \"bg-default-100 rounded-lg p-3 w-full mx-auto\";\n\n return (\n <div className={[\"flex flex-col gap-2\", containerClass].join(\" \")}>\n {/* User Info Skeleton */}\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"w-10 h-10 rounded-full\" />\n <div className=\"flex flex-col gap-1 flex-1\">\n <Skeleton className=\"h-4 w-24\" />\n <Skeleton className=\"h-3 w-16\" />\n </div>\n <Skeleton className=\"h-3 w-12\" />\n </div>\n\n {/* Content Skeleton */}\n <div className=\"flex flex-col gap-2\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-4 w-1/2\" />\n </div>\n\n {/* Media Skeleton */}\n <Skeleton className=\"h-48 w-full rounded-lg\" />\n\n {/* Actions Skeleton */}\n <div className=\"flex justify-between items-center pt-2\">\n <div className=\"flex gap-4\">\n <Skeleton className=\"h-6 w-16\" />\n <Skeleton className=\"h-6 w-16\" />\n <Skeleton className=\"h-6 w-16\" />\n </div>\n <Skeleton className=\"h-6 w-20\" />\n </div>\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { Avatar, Badge, Button, Image } from \"@liberfi.io/ui\";\nimport { formatPercent, SafeBigNumber } from \"@liberfi.io/utils\";\nimport { MediaToken } from \"../../../../types\";\n\ntype Props = {\n token: MediaToken;\n};\n\nexport function TweetTokenButton({ token }: Props) {\n const color = new SafeBigNumber(token.priceChange ?? \"0\").isPositive()\n ? \"primary\"\n : \"danger\";\n\n return (\n <Button\n color={color}\n variant=\"flat\"\n size=\"sm\"\n radius=\"full\"\n startContent={<TweetTokenIcon token={token} />}\n >\n <span>{token.symbol}</span>\n <span>\n {token.priceChange\n ? formatPercent(Number(token.priceChange) / 100)\n : \"--\"}\n </span>\n </Button>\n );\n}\n\nexport function TweetTokenIcon({ token }: Props) {\n const ChainIcon = useMemo(() => {\n return (\n <Image className=\"w-full h-full\" src={token.image} alt={token.chain} />\n );\n }, [token.chain, token.image]);\n\n return (\n <Badge\n className=\"w-2.5 h-2.5 p-0 border\"\n size=\"sm\"\n content={ChainIcon}\n shape=\"circle\"\n placement=\"bottom-right\"\n >\n <Avatar className=\"w-5 h-5\" radius=\"full\" src={token.image} />\n </Badge>\n );\n}\n","import { useCallback } from \"react\";\nimport { TweetMedia } from \"../../types\";\nimport { TweetTokenButton } from \"./tweet/tools/tweet-token-button\";\n// import { TweetTradeButton } from \"./tweet/tools/tweet-trade-button\";\nimport { TweetItem } from \"./tweet/tweet-item\";\n\ntype TweetsProps = {\n data: Array<TweetMedia>;\n loading: boolean;\n setIsPaused: (paused: boolean) => void;\n customHeaderActions?: (item: TweetMedia) => React.ReactNode;\n customFooterActions?: (item: TweetMedia) => React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function Tweets({\n data,\n loading,\n setIsPaused,\n customHeaderActions,\n customFooterActions,\n}: TweetsProps) {\n const footerActions = useCallback(\n (item: TweetMedia) => (\n <div className=\"flex gap-2.5 justify-between\">\n {item.token && <TweetTokenButton token={item.token} />}\n {customFooterActions?.(item)}\n {/* {item.token && <TweetTradeButton token={item.token} />} */}\n </div>\n ),\n [customFooterActions],\n );\n\n return (\n <div\n className=\"flex flex-col gap-2.5\"\n onMouseEnter={() => setIsPaused(true)}\n onMouseLeave={() => setIsPaused(false)}\n >\n {data.map((item: TweetMedia) => (\n <TweetItem\n key={item.id}\n data={item}\n headerActions={customHeaderActions?.(item)}\n footerActions={footerActions(item)}\n loading={loading}\n />\n ))}\n </div>\n );\n}\n","import { Skeleton } from \"@liberfi.io/ui\";\n\n// ------------------------------------------------------------\nexport function TweetSkeleton() {\n return (\n <div className=\"flex flex-col gap-2 bg-default-100 rounded-lg p-3 w-full mx-auto\">\n {/* User Info Skeleton */}\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"w-10 h-10 rounded-full\" />\n <div className=\"flex flex-col gap-1 flex-1\">\n <Skeleton className=\"h-4 w-40 rounded-md\" />\n <Skeleton className=\"h-3 w-32 rounded-md\" />\n </div>\n </div>\n\n {/* Content Skeleton */}\n <div className=\"flex flex-col gap-2\">\n <Skeleton className=\"h-4 w-full rounded-md\" />\n <Skeleton className=\"h-4 w-3/4 rounded-md\" />\n <Skeleton className=\"h-4 w-1/2 rounded-md\" />\n </div>\n\n {/* Media Skeleton */}\n <Skeleton className=\"h-48 w-full rounded-lg\" />\n </div>\n );\n}\n\nexport function TweetSkeletonList({ count = 3 }: { count: number }) {\n return (\n <div className=\"flex flex-col gap-2\">\n {Array.from({ length: count }).map((_, index) => (\n <TweetSkeleton key={index} />\n ))}\n </div>\n );\n}\n","import { useCallback, useEffect, useState } from \"react\";\nimport { useMediaTrackRuntime } from \"../../hooks/useMediaTrackRuntime\";\nimport { TweetMedia } from \"../../types\";\n\nexport const useTweets = () => {\n const [medias, setMedias] = useState<Array<TweetMedia>>([]);\n const [loading, setLoading] = useState(true);\n const [isPaused, setIsPaused] = useState(false);\n\n const runtime = useMediaTrackRuntime();\n\n const handleMedia = useCallback(\n (media: TweetMedia) => {\n setMedias((prevMedias) => {\n const idx = prevMedias.findIndex((it) => it.id === media.id);\n let newMedias: Array<TweetMedia>;\n\n if (idx >= 0) {\n newMedias = prevMedias.map((item, index) =>\n index === idx ? media : item,\n );\n } else {\n if (isPaused) {\n return prevMedias;\n }\n newMedias = [media, ...prevMedias];\n }\n\n return newMedias.slice(0, 30);\n });\n setLoading(false);\n },\n [isPaused],\n );\n\n useEffect(() => {\n const subTweet = runtime.subscribe(\"x-monitor-basic\", handleMedia);\n const subTweetToken = runtime.subscribe(\"x-monitor-token\", handleMedia);\n return () => {\n subTweet.unsubscribe();\n subTweetToken.unsubscribe();\n };\n }, [runtime, handleMedia]);\n\n return { medias, loading, isPaused, setIsPaused };\n};\n","import { useEffect } from \"react\";\nimport { TweetMedia } from \"../../types\";\nimport { TweetSkeletonList } from \"./tweet/tweet-skeleton\";\nimport { useTweets } from \"./tweets.script\";\nimport { Tweets } from \"./tweets.ui\";\n\n// ------------------------------------------------------------\nexport type TweetsWidgetProps = {\n onPauseChange?: (paused: boolean) => void;\n customHeaderActions?: (item: TweetMedia) => React.ReactNode;\n customFooterActions?: (item: TweetMedia) => React.ReactNode;\n};\n\nexport function TweetsWidget({\n onPauseChange,\n customHeaderActions,\n customFooterActions,\n}: TweetsWidgetProps) {\n const { medias, loading, isPaused, setIsPaused } = useTweets();\n\n useEffect(() => {\n onPauseChange?.(isPaused);\n }, [isPaused, onPauseChange]);\n\n if (loading) {\n return <TweetSkeletonList count={3} />;\n }\n\n return (\n <Tweets\n data={medias}\n loading={loading}\n setIsPaused={setIsPaused}\n customHeaderActions={customHeaderActions}\n customFooterActions={customFooterActions}\n />\n );\n}\n","export type MediaTrackUnsubscribe = () => void;\n\nexport interface MediaTrackSubscription {\n unsubscribe: MediaTrackUnsubscribe;\n}\n\nexport interface MediaTrackRuntime<T = unknown> {\n readonly generation: number;\n connect(): void;\n disconnect(): void;\n setLocaleTransform(transform: ((payload: T) => T) | null): void;\n subscribe(channel: string, listener: (payload: T) => void): MediaTrackSubscription;\n publish(channel: string, payload: T): void;\n}\n\nexport function createMediaTrackRuntime<T = unknown>(): MediaTrackRuntime<T> {\n let generation = 0;\n let connected = false;\n let localeTransform: ((payload: T) => T) | null = null;\n const listeners = new Map<string, Set<(payload: T) => void>>();\n\n return {\n get generation() {\n return generation;\n },\n connect() {\n generation += 1;\n connected = true;\n },\n disconnect() {\n connected = false;\n },\n setLocaleTransform(transform) {\n localeTransform = transform;\n },\n subscribe(channel, listener) {\n let bucket = listeners.get(channel);\n if (!bucket) {\n bucket = new Set();\n listeners.set(channel, bucket);\n }\n bucket.add(listener);\n let unsubscribed = false;\n return {\n unsubscribe() {\n if (unsubscribed) return;\n unsubscribed = true;\n const current = listeners.get(channel);\n current?.delete(listener);\n if (current && current.size === 0) {\n listeners.delete(channel);\n }\n },\n };\n },\n publish(channel, payload) {\n if (!connected) return;\n const next = localeTransform ? localeTransform(payload) : payload;\n listeners.get(channel)?.forEach((listener) => listener(next));\n },\n };\n}\n","import { PropsWithChildren, useContext, useEffect, useMemo } from \"react\";\nimport { MediaTrackContext } from \"../context\";\nimport { MediaTrackRuntimeContext } from \"../context/MediaTrackRuntimeContext\";\nimport { createMediaTrackRuntime } from \"../runtime/media-track-runtime\";\nimport type { IMediaTrackClient, TweetMedia } from \"../types\";\n\nexport type MediaTrackProviderProps = PropsWithChildren<{\n client: IMediaTrackClient;\n}>;\n\nexport function MediaTrackProvider({\n client,\n children,\n}: MediaTrackProviderProps) {\n const runtime = useMemo(() => createMediaTrackRuntime<TweetMedia>(), []);\n\n return (\n <MediaTrackContext.Provider value={{ client }}>\n <MediaTrackRuntimeContext.Provider value={runtime}>\n <MediaTrackClientBridge client={client} />\n {children}\n </MediaTrackRuntimeContext.Provider>\n </MediaTrackContext.Provider>\n );\n}\n\nfunction MediaTrackClientBridge({ client }: { client: IMediaTrackClient }) {\n const runtime = useContext(MediaTrackRuntimeContext);\n useEffect(() => {\n if (!runtime) return;\n runtime.connect();\n const basic = client.subscribeTweetMedia({\n callback: (media) => runtime.publish(\"x-monitor-basic\", media),\n });\n const token = client.subscribeTweetMediaToken({\n callback: (media) => runtime.publish(\"x-monitor-token\", media),\n });\n return () => {\n basic.unsubscribe();\n token.unsubscribe();\n runtime.disconnect();\n };\n }, [client, runtime]);\n return null;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/components/tweets/tweet/media/media-image.tsx","../src/components/tweets/tweet/media/media-video.tsx","../src/components/tweets/tweet/media/medias.tsx","../src/components/tweets/tweet/user/user-avatar.tsx","../src/components/tweets/tweet/user/user-info.tsx","../src/context/MediaTrackContext.ts","../src/context/MediaTrackRuntimeContext.ts","../src/hooks/useMediaTrackContext.ts","../src/hooks/useMediaTrackClient.ts","../src/hooks/useGenerateTweetMediaMemeMutation.ts","../src/hooks/useMediaTrackRuntime.ts","../src/hooks/useTranslateTweetMediaQuery.ts","../src/utils/parseText.tsx","../src/components/tweets/tweet/tools/translate.tsx","../src/components/tweets/tweet/tools/text-expand.tsx","../src/components/tweets/tweet/content/index.tsx","../src/components/tweets/tweet/tweet-source.tsx","../src/components/tweets/tweet/tweet-original.tsx","../src/components/tweets/tweet/tweet-quote.tsx","../src/components/tweets/tweet/tweet-reply.tsx","../src/components/tweets/tweet/tweet-retweet.tsx","../src/components/tweets/tweet/tweet-item.tsx","../src/components/tweets/tweet/tools/tweet-token-button.tsx","../src/components/tweets/tweets.ui.tsx","../src/components/tweets/tweet/tweet-skeleton.tsx","../src/components/tweets/tweets.script.ts","../src/components/tweets/tweets.widget.tsx","../src/runtime/media-track-runtime.ts","../src/providers/MediaTrackProvider.tsx"],"names":["MediaImage","src","isLoaded","setTrue","useBoolean","jsx","Skeleton","MediaVideo","Medias","medias","tweetHref","images","media","videos","renderVideos","video","renderImages","image","Link","jsxs","UserAvatar","url","name","size","fallbackName","useMemo","Avatar","UserInfo","user","renderTimestamp","renderActions","twitterUserUrl","MediaTrackContext","createContext","MediaTrackRuntimeContext","useMediaTrackContext","context","useContext","useMediaTrackClient","client","useGenerateTweetMediaMemeMutation","options","useMutation","params","useMediaTrackRuntime","runtime","translateTweetMedia","targetLanguage","useTranslateTweetMediaMutation","parseText","text","urlRegex","hashtagRegex","symbolRegex","matches","match","matchIndex","a","b","parts","lastIndex","key","item","e","hashtagUrl","Translate","data","embed","isTranslate","toggle","t","i18n","useTranslation","isTranslating","translatedText","setTranslatedText","useState","handleTranslate","useCallback","parsedText","Fragment","TranslateIcon","cn","TextExpand","isExpanded","onToggleExpand","renderExpand","ChevronUpIcon","ChevronDownIcon","Content","content","onLoad","ref","useRef","parsedContent","useEffect","current","TweetSource","headerActions","footerActions","indicator","children","setIsExpanded","containerClass","tweet","age","useTickAge","twitterTweetUrl","formatAge","TweetOriginal","TweetQuote","hasSource","TweetReply","sourceTweet","TweetRetweet","TweetItem","loading","TweetSkeleton","tweetType","commonProps","TweetTokenButton","token","color","SafeBigNumber","Button","TweetTokenIcon","formatPercent","ChainIcon","Image","Badge","Tweets","setIsPaused","customHeaderActions","customFooterActions","TweetSkeletonList","count","_","index","useTweets","setMedias","setLoading","isPaused","handleMedia","prevMedias","idx","it","newMedias","subTweet","subTweetToken","TweetsWidget","onPauseChange","createMediaTrackRuntime","generation","connected","localeTransform","listeners","transform","channel","listener","bucket","unsubscribed","payload","next","MediaTrackProvider","MediaTrackClientBridge","basic"],"mappings":"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","file":"index.mjs","sourcesContent":["import { useBoolean } from \"@liberfi.io/hooks\";\nimport { Skeleton } from \"@liberfi.io/ui\";\n\ntype Props = {\n src: string;\n};\n\n// ------------------------------------------------------------\nexport function MediaImage({ src }: Props) {\n const [isLoaded, { setTrue }] = useBoolean(false);\n if (!src) return null;\n\n return (\n <Skeleton isLoaded={isLoaded} className=\"w-full h-auto\">\n <img\n src={src}\n className=\"w-full h-full object-cover aspect-video\"\n onLoad={() => {\n setTrue();\n }}\n />\n </Skeleton>\n );\n}\n","type Props = {\n src: string;\n};\n\n// ------------------------------------------------------------\nexport function MediaVideo({ src }: Props) {\n if (!src) return null;\n\n return (\n <div className=\"w-full h-full overflow-hidden rounded-md mt-2\">\n <iframe\n className=\"w-full h-full aspect-video\"\n src={src}\n allowFullScreen\n />\n </div>\n );\n}\n","import { Link } from \"@liberfi.io/ui\";\nimport { TweetContentMedia } from \"../../../../types\";\nimport { MediaImage } from \"./media-image\";\nimport { MediaVideo } from \"./media-video\";\n\ntype Props = {\n medias: Array<TweetContentMedia>;\n tweetHref: string;\n};\n\nexport function Medias({ medias, tweetHref }: Props) {\n const images = medias.filter((media) => media.type === \"image\");\n const videos = medias.filter((media) => media.type === \"video\");\n\n const renderVideos = () => {\n if (!videos.length) return null;\n return (\n <div className={`grid grid-cols-1 gap-[1px] overflow-hidden rounded-md`}>\n {videos.map((video) => (\n <MediaVideo key={video.url} src={video.url} />\n ))}\n </div>\n );\n };\n\n const renderImages = () => {\n if (!images.length) return null;\n return (\n <div className={`grid grid-cols-1 gap-[1px] overflow-hidden rounded-md`}>\n {images.map((image) => (\n <Link key={image.url} href={tweetHref} target=\"_blank\">\n <MediaImage src={image.url} />\n </Link>\n ))}\n </div>\n );\n };\n\n return (\n <div className=\"flex flex-col gap-2\">\n {renderVideos()}\n {renderImages()}\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { Avatar, Skeleton } from \"@liberfi.io/ui\";\n\ntype Props = {\n url?: string;\n name?: string;\n size?: number;\n};\n\nexport function UserAvatar({ url, name = \"\", size = 36 }: Props) {\n const fallbackName = useMemo(() => (name ? name.slice(0, 2) : \"N/A\"), [name]);\n\n return (\n <Skeleton\n className=\"flex rounded-full flex-shrink-0\"\n style={{ width: size, height: size }}\n isLoaded={!!url}\n >\n <Avatar\n size=\"md\"\n color=\"primary\"\n radius=\"full\"\n showFallback\n name={fallbackName}\n src={url}\n style={{ width: size, height: size }}\n />\n </Skeleton>\n );\n}\n","import React from \"react\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetUser } from \"../../../../types\";\nimport { UserAvatar } from \"./user-avatar\";\n\ntype Props = {\n user: TweetUser;\n renderTimestamp?: React.ReactNode;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function UserInfo({ user, renderTimestamp, renderActions }: Props) {\n return (\n <div className=\"flex items-center justify-between gap-1\">\n <div className=\"flex items-center gap-1\">\n <UserAvatar url={user.avatar} name={user.username} />\n <div className=\"flex flex-col gap-0.5\">\n <div className=\"flex flex-row items-baseline gap-1\">\n <span className=\"text-foreground font-semibold truncate leading-none\">\n {user.username}\n </span>\n {renderTimestamp}\n </div>\n <Link\n target=\"_blank\"\n underline=\"hover\"\n className=\"text-text-muted text-sm leading-none\"\n href={twitterUserUrl(user.screenName ?? user.username)}\n >\n @{user.screenName ?? user.username}\n </Link>\n </div>\n </div>\n {renderActions}\n </div>\n );\n}\n","import { createContext } from \"react\";\nimport { IMediaTrackClient } from \"../types\";\n\nexport interface MediaTrackContextValue {\n client: IMediaTrackClient;\n}\n\nexport const MediaTrackContext = createContext<MediaTrackContextValue>(\n {} as MediaTrackContextValue,\n);\n","import { createContext } from \"react\";\nimport type { TweetMedia } from \"../types\";\nimport type { MediaTrackRuntime } from \"../runtime/media-track-runtime\";\n\nexport const MediaTrackRuntimeContext =\n createContext<MediaTrackRuntime<TweetMedia> | null>(null);\n","import { useContext } from \"react\";\nimport { MediaTrackContext } from \"../context\";\n\nexport function useMediaTrackContext() {\n const context = useContext(MediaTrackContext);\n if (!context) {\n throw new Error(\n \"useMediaTrackContext must be used within a MediaTrackProvider\",\n );\n }\n return context;\n}\n","import { useMediaTrackContext } from \"./useMediaTrackContext\";\n\nexport function useMediaTrackClient() {\n const { client } = useMediaTrackContext();\n return client;\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport { GeneratedMemeInfo, TweetMedia } from \"../types\";\nimport { useMediaTrackClient } from \"./useMediaTrackClient\";\n\nexport function useGenerateTweetMediaMemeMutation(\n options: Omit<\n UseMutationOptions<GeneratedMemeInfo, Error, TweetMedia, string[]>,\n \"mutationFn\"\n > = {},\n) {\n const client = useMediaTrackClient();\n return useMutation({\n mutationFn: async (params: TweetMedia) => client.generateMeme(params),\n ...options,\n });\n}\n","import { useContext } from \"react\";\nimport { MediaTrackRuntimeContext } from \"../context/MediaTrackRuntimeContext\";\n\nexport function useMediaTrackRuntime() {\n const runtime = useContext(MediaTrackRuntimeContext);\n if (!runtime) {\n throw new Error(\n \"useMediaTrackRuntime must be used within a MediaTrackProvider\",\n );\n }\n return runtime;\n}\n","import { useMutation, UseMutationOptions } from \"@tanstack/react-query\";\nimport { LocaleCode } from \"@liberfi.io/i18n\";\nimport { IMediaTrackClient, TweetMedia } from \"../types\";\nimport { useMediaTrackClient } from \"./useMediaTrackClient\";\n\nexport interface UseTranslateTweetMediaParams {\n media: TweetMedia;\n targetLanguage: LocaleCode;\n options?: {\n sourceLanguage?: LocaleCode;\n sourceTweet?: boolean;\n };\n}\n\nexport async function translateTweetMedia(\n client: IMediaTrackClient,\n { media, targetLanguage, options }: UseTranslateTweetMediaParams,\n) {\n return await client.translate(media, targetLanguage, options);\n}\n\nexport function useTranslateTweetMediaMutation(\n options: Omit<\n UseMutationOptions<string, Error, UseTranslateTweetMediaParams>,\n \"mutationFn\"\n > = {},\n) {\n const client = useMediaTrackClient();\n return useMutation({\n mutationFn: async (params: UseTranslateTweetMediaParams) =>\n translateTweetMedia(client, params),\n ...options,\n });\n}\n","interface MatchItem {\n index: number;\n length: number;\n text: string;\n type: \"url\" | \"hashtag\" | \"symbol\";\n}\n\nexport function parseText(text: string): (string | React.ReactElement)[] {\n const urlRegex = /(https?:\\/\\/[^\\s]+|www\\.[^\\s]+)/gi;\n const hashtagRegex = /#[\\w]+/g;\n const symbolRegex = /\\$[A-Za-z][A-Za-z0-9_]*/g;\n\n const matches: MatchItem[] = [];\n let match: RegExpExecArray | null;\n\n while ((match = urlRegex.exec(text)) !== null) {\n matches.push({\n index: match.index,\n length: match[0].length,\n text: match[0],\n type: \"url\",\n });\n }\n\n while ((match = hashtagRegex.exec(text)) !== null) {\n const matchIndex = match.index;\n const overlaps = matches.some(\n (m) => matchIndex >= m.index && matchIndex < m.index + m.length,\n );\n if (!overlaps) {\n matches.push({\n index: matchIndex,\n length: match[0].length,\n text: match[0],\n type: \"hashtag\",\n });\n }\n }\n\n while ((match = symbolRegex.exec(text)) !== null) {\n const matchIndex = match.index;\n const overlaps = matches.some(\n (m) => matchIndex >= m.index && matchIndex < m.index + m.length,\n );\n if (!overlaps) {\n matches.push({\n index: matchIndex,\n length: match[0].length,\n text: match[0],\n type: \"symbol\",\n });\n }\n }\n\n matches.sort((a, b) => a.index - b.index);\n\n const parts: (string | React.ReactElement)[] = [];\n let lastIndex = 0;\n let key = 0;\n\n matches.forEach((item) => {\n if (item.index > lastIndex) {\n parts.push(text.slice(lastIndex, item.index));\n }\n\n if (item.type === \"url\") {\n const url = item.text.startsWith(\"http\")\n ? item.text\n : `https://${item.text}`;\n parts.push(\n <a\n key={key++}\n href={url}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline\"\n onClick={(e) => e.stopPropagation()}\n >\n {item.text}\n </a>,\n );\n } else if (item.type === \"hashtag\") {\n const hashtag = item.text.slice(1); // 移除 #\n const hashtagUrl = `https://x.com/hashtag/${hashtag}`;\n parts.push(\n <a\n key={key++}\n href={hashtagUrl}\n target=\"_blank\"\n rel=\"noopener noreferrer\"\n className=\"text-primary hover:underline\"\n onClick={(e) => e.stopPropagation()}\n >\n {item.text}\n </a>,\n );\n } else if (item.type === \"symbol\") {\n parts.push(\n <span key={key++} className=\"text-primary\">\n {item.text}\n </span>,\n );\n }\n\n lastIndex = item.index + item.length;\n });\n\n if (lastIndex < text.length) {\n parts.push(text.slice(lastIndex));\n }\n\n return parts.length > 0 ? parts : [text];\n}\n","import React, { MouseEvent, useCallback, useState } from \"react\";\nimport { useBoolean } from \"@liberfi.io/hooks\";\nimport { LocaleCode, useTranslation } from \"@liberfi.io/i18n\";\nimport { cn, Skeleton, TranslateIcon } from \"@liberfi.io/ui\";\nimport { useTranslateTweetMediaMutation } from \"../../../../hooks\";\nimport { TweetMedia } from \"../../../../types\";\nimport { parseText } from \"../../../../utils\";\n\ntype Props = {\n data: TweetMedia;\n embed?: boolean;\n text: string;\n renderActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function Translate({ data, embed, renderActions }: Props) {\n const [isTranslate, { toggle }] = useBoolean(false);\n\n const { t, i18n } = useTranslation();\n\n const { mutateAsync: translateTweetMedia, isPending: isTranslating } =\n useTranslateTweetMediaMutation();\n\n const [translatedText, setTranslatedText] = useState<\n (string | React.ReactElement)[] | null\n >(null);\n\n const handleTranslate = useCallback(\n async (e: MouseEvent<HTMLDivElement>) => {\n e.stopPropagation();\n toggle();\n if (!translatedText) {\n const text = await translateTweetMedia({\n media: data,\n targetLanguage: i18n.language as LocaleCode,\n options: {\n sourceTweet: embed,\n },\n });\n const parsedText = parseText(text);\n setTranslatedText(parsedText);\n }\n },\n [toggle, translateTweetMedia, data, i18n.language, translatedText, embed],\n );\n\n return (\n <>\n <div className=\"flex items-center gap-1 text-xs\">\n <div\n onClick={handleTranslate}\n className=\"flex items-center gap-0.5 cursor-pointer text-primary hover:text-foreground\"\n >\n <TranslateIcon width=\"14\" height=\"14\" />\n {isTranslate\n ? t(\"mediaTrack.tweets.translate.hide\")\n : t(\"mediaTrack.tweets.translate.show\")}\n </div>\n {renderActions}\n </div>\n <div\n className={cn(!isTranslate && \"hidden\")}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n {isTranslate && (\n <div className=\"bg-content2 rounded-md p-2 text-text-primary text-sm leading-5\">\n {translatedText}\n {isTranslating && <Skeleton className=\"w-full h-4 rounded-md\" />}\n </div>\n )}\n </div>\n </>\n );\n}\n","import { useTranslation } from \"@liberfi.io/i18n\";\nimport { ChevronDownIcon, ChevronUpIcon } from \"@liberfi.io/ui\";\n\ntype Props = {\n isExpanded?: boolean;\n onToggleExpand?: (expanded: boolean) => void;\n};\n\nexport function TextExpand({ isExpanded, onToggleExpand }: Props) {\n const { t } = useTranslation();\n const renderExpand = () => {\n if (isExpanded) {\n return (\n <>\n <ChevronUpIcon\n className=\"border border-current\"\n width=\"12\"\n height=\"12\"\n />\n {t(\"mediaTrack.tweets.collapse\")}\n </>\n );\n }\n\n return (\n <>\n <ChevronDownIcon\n className=\"border border-current\"\n width=\"12\"\n height=\"12\"\n />\n {t(\"mediaTrack.tweets.expand\")}\n </>\n );\n };\n\n if (isExpanded === undefined) return null;\n\n return (\n <div className=\"flex items-center gap-1\">\n <div className=\"w-px h-2.5 bg-line-300\" />\n <button\n onClick={(e) => {\n e.stopPropagation();\n onToggleExpand?.(!isExpanded);\n }}\n className=\"flex items-center text-text-muted hover:text-foreground text-xs\"\n >\n {renderExpand()}\n </button>\n </div>\n );\n}\n","import { useEffect, useMemo, useRef } from \"react\";\nimport { parseText } from \"../../../../utils\";\n\ntype Props = {\n content: string;\n isExpanded?: boolean;\n onLoad?: () => void;\n};\n\n// ------------------------------------------------------------\nexport function Content({ content, isExpanded = false, onLoad }: Props) {\n const ref = useRef<HTMLDivElement>(null);\n\n const parsedContent = useMemo(() => parseText(content), [content]);\n\n useEffect(() => {\n const current = ref.current;\n if (!onLoad || !current) return;\n if (current.scrollHeight > current.clientHeight) {\n onLoad?.();\n }\n }, [isExpanded, onLoad]);\n\n return (\n <div\n ref={ref}\n className={[\n \"text-text-primary text-sm leading-5\",\n !isExpanded ? \"line-clamp-3\" : \"\",\n ].join(\" \")}\n onClick={(e) => {\n e.stopPropagation();\n }}\n >\n {parsedContent}\n </div>\n );\n}\n","import React, { useMemo, useState } from \"react\";\nimport { useTickAge } from \"@liberfi.io/hooks\";\nimport { cn } from \"@liberfi.io/ui\";\nimport { formatAge, twitterTweetUrl } from \"@liberfi.io/utils\";\nimport { Tweet, TweetMedia } from \"../../../types\";\nimport { Content } from \"./content\";\nimport { Medias } from \"./media\";\nimport { Translate, TextExpand } from \"./tools\";\nimport { UserInfo } from \"./user\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n embed?: boolean;\n indicator?: React.ReactNode;\n children?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetSource({\n data,\n headerActions,\n footerActions,\n embed = false,\n indicator,\n children,\n}: Props) {\n const [isExpanded, setIsExpanded] = useState<boolean | undefined>(undefined);\n\n const containerClass = useMemo(() => {\n return embed\n ? \"bg-default-50 rounded-lg p-3 w-full mx-auto\"\n : \"bg-default-100 hover:bg-default-200 rounded-lg p-3 w-full mx-auto\";\n }, [embed]);\n\n const tweet = useMemo(\n () => (embed ? data.sourceTweet! : data.tweet),\n [data, embed],\n );\n\n const age = useTickAge((tweet as Tweet).timestamp);\n\n return (\n <div\n className={cn(\"flex flex-col gap-1.5 cursor-pointer\", containerClass)}\n onClick={() => {\n window.open(twitterTweetUrl(tweet.tweetId), \"_blank\");\n }}\n >\n {/* -------- USER INFO -------- */}\n <UserInfo\n user={tweet.user}\n renderTimestamp={\n embed ? undefined : (\n <div className=\"text-xs text-primary\">{formatAge(age)}</div>\n )\n }\n renderActions={headerActions}\n />\n\n {/* -------- MESSAGE TYPE INDICATOR -------- */}\n {indicator}\n\n {/* -------- CONTENT -------- */}\n {tweet.content.text && (\n <Content\n content={tweet.content.text}\n isExpanded={isExpanded}\n onLoad={() => setIsExpanded(false)}\n />\n )}\n\n {/* -------- TOOLS -------- */}\n {tweet.content.text && (\n <Translate\n data={data}\n embed={embed}\n text={tweet.content.text}\n renderActions={\n <TextExpand\n isExpanded={isExpanded}\n onToggleExpand={setIsExpanded}\n />\n }\n />\n )}\n\n {/* -------- MEDIA -------- */}\n <div\n className={cn(\n (!tweet.content.medias || tweet.content.medias.length === 0) &&\n \"hidden\",\n )}\n >\n {tweet.content.medias && tweet.content.medias.length > 0 && (\n <Medias\n medias={tweet.content.medias}\n tweetHref={twitterTweetUrl(tweet.tweetId)}\n />\n )}\n </div>\n\n {/* -------- CHILDREN -------- */}\n {children}\n\n {/* -------- Custom ACTIONS -------- */}\n {footerActions}\n </div>\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetOriginal({ data, headerActions, footerActions }: Props) {\n return (\n <TweetSource\n data={data}\n headerActions={headerActions}\n footerActions={footerActions}\n />\n );\n}\n","import React from \"react\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetQuote({ data, headerActions, footerActions }: Props) {\n const sourceTweet = data.sourceTweet;\n const hasSource = !!sourceTweet;\n\n return (\n <TweetSource\n data={data}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { useTranslation } from \"@liberfi.io/i18n\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetReply({ data, headerActions, footerActions }: Props) {\n const { t } = useTranslation();\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>{t(\"mediaTrack.replyingTo\")}</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, t],\n );\n\n return (\n <TweetSource\n data={data}\n indicator={indicator}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React, { useMemo } from \"react\";\nimport { useTranslation } from \"@liberfi.io/i18n\";\nimport { Link } from \"@liberfi.io/ui\";\nimport { twitterUserUrl } from \"@liberfi.io/utils\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetSource } from \"./tweet-source\";\n\ntype Props = {\n data: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function TweetRetweet({ data, headerActions, footerActions }: Props) {\n const { t } = useTranslation();\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>{t(\"mediaTrack.retweetedBy\")}</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, t],\n );\n\n return (\n <TweetSource\n data={data}\n indicator={indicator}\n headerActions={headerActions}\n footerActions={footerActions}\n >\n {hasSource ? <TweetSource data={data} embed /> : null}\n </TweetSource>\n );\n}\n","import React from \"react\";\nimport { Skeleton } from \"@liberfi.io/ui\";\nimport { TweetMedia } from \"../../../types\";\nimport { TweetOriginal } from \"./tweet-original\";\nimport { TweetQuote } from \"./tweet-quote\";\nimport { TweetReply } from \"./tweet-reply\";\nimport { TweetRetweet } from \"./tweet-retweet\";\n\ntype Props = {\n data?: TweetMedia;\n headerActions?: React.ReactNode;\n footerActions?: React.ReactNode;\n embed?: boolean;\n children?: React.ReactNode;\n loading?: boolean;\n};\n\n// ------------------------------------------------------------\nexport function TweetItem({\n data,\n headerActions,\n footerActions,\n embed = false,\n children,\n loading = false,\n}: Props) {\n if (loading || !data) {\n return <TweetSkeleton embed={embed} />;\n }\n\n const tweetType = data.tweet.type;\n\n // Render appropriate component based on tweet type\n const renderTweetComponent = () => {\n const commonProps = {\n data,\n headerActions,\n footerActions,\n embed,\n children,\n };\n\n switch (tweetType) {\n case \"reply\":\n return <TweetReply {...commonProps} />;\n case \"retweet\":\n return <TweetRetweet {...commonProps} />;\n case \"quote\":\n return <TweetQuote {...commonProps} />;\n default: // \"original\"\n return <TweetOriginal {...commonProps} />;\n }\n };\n\n return <div className=\"w-full\">{renderTweetComponent()}</div>;\n}\n\n// ------------------------------------------------------------\nfunction TweetSkeleton({ embed = false }: { embed?: boolean }) {\n const containerClass = embed\n ? \"bg-default-50 rounded-lg p-3 w-full mx-auto\"\n : \"bg-default-100 rounded-lg p-3 w-full mx-auto\";\n\n return (\n <div className={[\"flex flex-col gap-2\", containerClass].join(\" \")}>\n {/* User Info Skeleton */}\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"w-10 h-10 rounded-full\" />\n <div className=\"flex flex-col gap-1 flex-1\">\n <Skeleton className=\"h-4 w-24\" />\n <Skeleton className=\"h-3 w-16\" />\n </div>\n <Skeleton className=\"h-3 w-12\" />\n </div>\n\n {/* Content Skeleton */}\n <div className=\"flex flex-col gap-2\">\n <Skeleton className=\"h-4 w-full\" />\n <Skeleton className=\"h-4 w-3/4\" />\n <Skeleton className=\"h-4 w-1/2\" />\n </div>\n\n {/* Media Skeleton */}\n <Skeleton className=\"h-48 w-full rounded-lg\" />\n\n {/* Actions Skeleton */}\n <div className=\"flex justify-between items-center pt-2\">\n <div className=\"flex gap-4\">\n <Skeleton className=\"h-6 w-16\" />\n <Skeleton className=\"h-6 w-16\" />\n <Skeleton className=\"h-6 w-16\" />\n </div>\n <Skeleton className=\"h-6 w-20\" />\n </div>\n </div>\n );\n}\n","import { useMemo } from \"react\";\nimport { Avatar, Badge, Button, Image } from \"@liberfi.io/ui\";\nimport { formatPercent, SafeBigNumber } from \"@liberfi.io/utils\";\nimport { MediaToken } from \"../../../../types\";\n\ntype Props = {\n token: MediaToken;\n};\n\nexport function TweetTokenButton({ token }: Props) {\n const color = new SafeBigNumber(token.priceChange ?? \"0\").isPositive()\n ? \"primary\"\n : \"danger\";\n\n return (\n <Button\n color={color}\n variant=\"flat\"\n size=\"sm\"\n radius=\"full\"\n startContent={<TweetTokenIcon token={token} />}\n >\n <span>{token.symbol}</span>\n <span>\n {token.priceChange\n ? formatPercent(Number(token.priceChange) / 100)\n : \"--\"}\n </span>\n </Button>\n );\n}\n\nexport function TweetTokenIcon({ token }: Props) {\n const ChainIcon = useMemo(() => {\n return (\n <Image className=\"w-full h-full\" src={token.image} alt={token.chain} />\n );\n }, [token.chain, token.image]);\n\n return (\n <Badge\n className=\"w-2.5 h-2.5 p-0 border\"\n size=\"sm\"\n content={ChainIcon}\n shape=\"circle\"\n placement=\"bottom-right\"\n >\n <Avatar className=\"w-5 h-5\" radius=\"full\" src={token.image} />\n </Badge>\n );\n}\n","import { useCallback } from \"react\";\nimport { TweetMedia } from \"../../types\";\nimport { TweetTokenButton } from \"./tweet/tools/tweet-token-button\";\n// import { TweetTradeButton } from \"./tweet/tools/tweet-trade-button\";\nimport { TweetItem } from \"./tweet/tweet-item\";\n\ntype TweetsProps = {\n data: Array<TweetMedia>;\n loading: boolean;\n setIsPaused: (paused: boolean) => void;\n customHeaderActions?: (item: TweetMedia) => React.ReactNode;\n customFooterActions?: (item: TweetMedia) => React.ReactNode;\n};\n\n// ------------------------------------------------------------\nexport function Tweets({\n data,\n loading,\n setIsPaused,\n customHeaderActions,\n customFooterActions,\n}: TweetsProps) {\n const footerActions = useCallback(\n (item: TweetMedia) => (\n <div className=\"flex gap-2.5 justify-between\">\n {item.token && <TweetTokenButton token={item.token} />}\n {customFooterActions?.(item)}\n {/* {item.token && <TweetTradeButton token={item.token} />} */}\n </div>\n ),\n [customFooterActions],\n );\n\n return (\n <div\n className=\"flex flex-col gap-2.5\"\n onMouseEnter={() => setIsPaused(true)}\n onMouseLeave={() => setIsPaused(false)}\n >\n {data.map((item: TweetMedia) => (\n <TweetItem\n key={item.id}\n data={item}\n headerActions={customHeaderActions?.(item)}\n footerActions={footerActions(item)}\n loading={loading}\n />\n ))}\n </div>\n );\n}\n","import { Skeleton } from \"@liberfi.io/ui\";\n\n// ------------------------------------------------------------\nexport function TweetSkeleton() {\n return (\n <div className=\"flex flex-col gap-2 bg-default-100 rounded-lg p-3 w-full mx-auto\">\n {/* User Info Skeleton */}\n <div className=\"flex items-center gap-3\">\n <Skeleton className=\"w-10 h-10 rounded-full\" />\n <div className=\"flex flex-col gap-1 flex-1\">\n <Skeleton className=\"h-4 w-40 rounded-md\" />\n <Skeleton className=\"h-3 w-32 rounded-md\" />\n </div>\n </div>\n\n {/* Content Skeleton */}\n <div className=\"flex flex-col gap-2\">\n <Skeleton className=\"h-4 w-full rounded-md\" />\n <Skeleton className=\"h-4 w-3/4 rounded-md\" />\n <Skeleton className=\"h-4 w-1/2 rounded-md\" />\n </div>\n\n {/* Media Skeleton */}\n <Skeleton className=\"h-48 w-full rounded-lg\" />\n </div>\n );\n}\n\nexport function TweetSkeletonList({ count = 3 }: { count: number }) {\n return (\n <div className=\"flex flex-col gap-2\">\n {Array.from({ length: count }).map((_, index) => (\n <TweetSkeleton key={index} />\n ))}\n </div>\n );\n}\n","import { useCallback, useEffect, useState } from \"react\";\nimport { useMediaTrackRuntime } from \"../../hooks/useMediaTrackRuntime\";\nimport { TweetMedia } from \"../../types\";\n\nexport const useTweets = () => {\n const [medias, setMedias] = useState<Array<TweetMedia>>([]);\n const [loading, setLoading] = useState(true);\n const [isPaused, setIsPaused] = useState(false);\n\n const runtime = useMediaTrackRuntime();\n\n const handleMedia = useCallback(\n (media: TweetMedia) => {\n setMedias((prevMedias) => {\n const idx = prevMedias.findIndex((it) => it.id === media.id);\n let newMedias: Array<TweetMedia>;\n\n if (idx >= 0) {\n newMedias = prevMedias.map((item, index) =>\n index === idx ? media : item,\n );\n } else {\n if (isPaused) {\n return prevMedias;\n }\n newMedias = [media, ...prevMedias];\n }\n\n return newMedias.slice(0, 30);\n });\n setLoading(false);\n },\n [isPaused],\n );\n\n useEffect(() => {\n const subTweet = runtime.subscribe(\"x-monitor-basic\", handleMedia);\n const subTweetToken = runtime.subscribe(\"x-monitor-token\", handleMedia);\n return () => {\n subTweet.unsubscribe();\n subTweetToken.unsubscribe();\n };\n }, [runtime, handleMedia]);\n\n return { medias, loading, isPaused, setIsPaused };\n};\n","import { useEffect } from \"react\";\nimport { TweetMedia } from \"../../types\";\nimport { TweetSkeletonList } from \"./tweet/tweet-skeleton\";\nimport { useTweets } from \"./tweets.script\";\nimport { Tweets } from \"./tweets.ui\";\n\n// ------------------------------------------------------------\nexport type TweetsWidgetProps = {\n onPauseChange?: (paused: boolean) => void;\n customHeaderActions?: (item: TweetMedia) => React.ReactNode;\n customFooterActions?: (item: TweetMedia) => React.ReactNode;\n};\n\nexport function TweetsWidget({\n onPauseChange,\n customHeaderActions,\n customFooterActions,\n}: TweetsWidgetProps) {\n const { medias, loading, isPaused, setIsPaused } = useTweets();\n\n useEffect(() => {\n onPauseChange?.(isPaused);\n }, [isPaused, onPauseChange]);\n\n if (loading) {\n return <TweetSkeletonList count={3} />;\n }\n\n return (\n <Tweets\n data={medias}\n loading={loading}\n setIsPaused={setIsPaused}\n customHeaderActions={customHeaderActions}\n customFooterActions={customFooterActions}\n />\n );\n}\n","export type MediaTrackUnsubscribe = () => void;\n\nexport interface MediaTrackSubscription {\n unsubscribe: MediaTrackUnsubscribe;\n}\n\nexport interface MediaTrackRuntime<T = unknown> {\n readonly generation: number;\n connect(): void;\n disconnect(): void;\n setLocaleTransform(transform: ((payload: T) => T) | null): void;\n subscribe(channel: string, listener: (payload: T) => void): MediaTrackSubscription;\n publish(channel: string, payload: T): void;\n}\n\nexport function createMediaTrackRuntime<T = unknown>(): MediaTrackRuntime<T> {\n let generation = 0;\n let connected = false;\n let localeTransform: ((payload: T) => T) | null = null;\n const listeners = new Map<string, Set<(payload: T) => void>>();\n\n return {\n get generation() {\n return generation;\n },\n connect() {\n generation += 1;\n connected = true;\n },\n disconnect() {\n connected = false;\n },\n setLocaleTransform(transform) {\n localeTransform = transform;\n },\n subscribe(channel, listener) {\n let bucket = listeners.get(channel);\n if (!bucket) {\n bucket = new Set();\n listeners.set(channel, bucket);\n }\n bucket.add(listener);\n let unsubscribed = false;\n return {\n unsubscribe() {\n if (unsubscribed) return;\n unsubscribed = true;\n const current = listeners.get(channel);\n current?.delete(listener);\n if (current && current.size === 0) {\n listeners.delete(channel);\n }\n },\n };\n },\n publish(channel, payload) {\n if (!connected) return;\n const next = localeTransform ? localeTransform(payload) : payload;\n listeners.get(channel)?.forEach((listener) => listener(next));\n },\n };\n}\n","import { PropsWithChildren, useContext, useEffect, useMemo } from \"react\";\nimport { MediaTrackContext } from \"../context\";\nimport { MediaTrackRuntimeContext } from \"../context/MediaTrackRuntimeContext\";\nimport { createMediaTrackRuntime } from \"../runtime/media-track-runtime\";\nimport type { IMediaTrackClient, TweetMedia } from \"../types\";\n\nexport type MediaTrackProviderProps = PropsWithChildren<{\n client: IMediaTrackClient;\n}>;\n\nexport function MediaTrackProvider({\n client,\n children,\n}: MediaTrackProviderProps) {\n const runtime = useMemo(() => createMediaTrackRuntime<TweetMedia>(), []);\n\n return (\n <MediaTrackContext.Provider value={{ client }}>\n <MediaTrackRuntimeContext.Provider value={runtime}>\n <MediaTrackClientBridge client={client} />\n {children}\n </MediaTrackRuntimeContext.Provider>\n </MediaTrackContext.Provider>\n );\n}\n\nfunction MediaTrackClientBridge({ client }: { client: IMediaTrackClient }) {\n const runtime = useContext(MediaTrackRuntimeContext);\n useEffect(() => {\n if (!runtime) return;\n runtime.connect();\n const basic = client.subscribeTweetMedia({\n callback: (media) => runtime.publish(\"x-monitor-basic\", media),\n });\n const token = client.subscribeTweetMediaToken({\n callback: (media) => runtime.publish(\"x-monitor-token\", media),\n });\n return () => {\n basic.unsubscribe();\n token.unsubscribe();\n runtime.disconnect();\n };\n }, [client, runtime]);\n return null;\n}\n"]}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@liberfi.io/ui-media-track",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.271",
|
|
4
4
|
"description": "Media Track for Liberfi React SDK",
|
|
5
5
|
"main": "dist/index.js",
|
|
6
6
|
"module": "dist/index.mjs",
|
|
@@ -28,11 +28,11 @@
|
|
|
28
28
|
"dependencies": {
|
|
29
29
|
"@chainstream-io/centrifuge": "^1.0.0",
|
|
30
30
|
"tailwind-variants": "^3.1.1",
|
|
31
|
-
"@liberfi.io/hooks": "0.1.
|
|
32
|
-
"@liberfi.io/i18n": "0.1.
|
|
33
|
-
"@liberfi.io/types": "0.4.
|
|
34
|
-
"@liberfi.io/ui": "0.3.
|
|
35
|
-
"@liberfi.io/utils": "0.2.
|
|
31
|
+
"@liberfi.io/hooks": "0.1.268",
|
|
32
|
+
"@liberfi.io/i18n": "0.1.273",
|
|
33
|
+
"@liberfi.io/types": "0.4.76",
|
|
34
|
+
"@liberfi.io/ui": "0.3.76",
|
|
35
|
+
"@liberfi.io/utils": "0.2.75"
|
|
36
36
|
},
|
|
37
37
|
"devDependencies": {
|
|
38
38
|
"@tanstack/react-query": "^5.90.2",
|
|
@@ -46,7 +46,7 @@
|
|
|
46
46
|
"ts-jest": "^29.4.6",
|
|
47
47
|
"tsup": "^8.5.0",
|
|
48
48
|
"typescript": "^5.9.2",
|
|
49
|
-
"tsconfig": "0.1.
|
|
49
|
+
"tsconfig": "0.1.259"
|
|
50
50
|
},
|
|
51
51
|
"peerDependencies": {
|
|
52
52
|
"@tanstack/react-query": "^5.90.2",
|