1 line
13 KiB
JavaScript
1 line
13 KiB
JavaScript
(function(m,I,g,p,n,A,d,B,O){"use strict";const i={DEFAULT_APP_NAME:"Music",DEFAULT_TIME_INTERVAL:5,APPLICATION_ID:"1054951789318909972",MIN_UPDATE_INTERVAL:3,MAX_RETRY_ATTEMPTS:3,RETRY_DELAY:5e3,LFM_API_BASE_URL:"https://ws.audioscrobbler.com/2.0",LFM_DEFAULT_COVER_HASHES:["2a96cbd8b46e442fc41c2b86b821562f","c6f59c1e5e7240a4c0d427abd71f3dbb"],DEFAULT_SETTINGS:{username:"",apiKey:"",appName:"Music",timeInterval:5,showTimestamp:!0,listeningTo:!0,ignoreSpotify:!0,verboseLogging:!1},GITHUB_URL:"https://github.com/kmmiio99o/letup",GITHUB_COMMITS_URL:"https://github.com/kmmiio99o/letup/commits/main/"};function P(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function k(e,t){for(var a=0;a<t.length;a++){var s=t[a];s.enumerable=s.enumerable||!1,s.configurable=!0,"value"in s&&(s.writable=!0),Object.defineProperty(e,s.key,s)}}function U(e,t,a){return t&&k(e.prototype,t),a&&k(e,a),e}d.findByProps("SET_ACTIVITY");const Y=d.findByProps("getAssetIds"),K=d.findByStoreName("SelfPresenceStore"),C=d.findByStoreName("UserStore");function w(){return D(null)}function D(e){l.pluginStopped&&(V(),e=null),l.lastActivity=e,n.FluxDispatcher.dispatch({type:"LOCAL_ACTIVITY_UPDATE",activity:e,pid:2312,socketId:"Last.fm@Vendetta"})}async function j(e,t=i.APPLICATION_ID){if(!e?.length)return[];try{return await Y.fetchAssetIds(t,e)}catch(a){return console.error("[Last.fm] Failed to fetch assets:",a),[]}}const v={};v.componentMountErrors=[],v.componentMountCount=0,v.settingsLoadAttempts=0;function h(e,t){v[e]=t}const F=function(){function e(){P(this,e)}return U(e,[{key:"validateSettings",value:function(){if(!c.username)throw new Error("Last.fm username is not set");if(!c.apiKey)throw new Error("Last.fm API key is not set")}},{key:"handleError",value:async function(t){this.lastError=t.error;const a={2:"Invalid API key",6:"User not found",11:"Service temporarily unavailable",16:"Service temporarily unavailable",29:"Rate limit exceeded"}[t.error]||t.message||"Unknown error";throw p.showToast(`Last.fm Error: ${a}`,g.getAssetIDByName("Small")),new Error(`Last.fm API Error ${t.error}: ${a}`)}},{key:"makeRequest",value:async function(t){const a=new URLSearchParams({...t,api_key:c.apiKey,format:"json"}).toString(),s=await fetch(`${i.LFM_API_BASE_URL}?${a}`),E=await s.json();return(!s.ok||E.error)&&await this.handleError(E),E}},{key:"fetchLatestScrobble",value:async function(){try{this.validateSettings();const t=(await this.makeRequest({method:"user.getrecenttracks",user:c.username,limit:"1",extended:"1"}))?.recenttracks?.track?.[0];if(h("lastAPIResponse",t),!t)throw new Error("No tracks found");return this.retryCount=0,{name:t.name,artist:t.artist.name,album:t.album["#text"],albumArt:await this.handleAlbumCover(t.image?.find(function(a){return a.size==="large"})?.["#text"]),url:t.url,date:t.date?.["#text"]??"now",nowPlaying:!!t["@attr"]?.nowplaying,loved:t.loved==="1"}}catch(t){if(this.retryCount++,this.retryCount>i.MAX_RETRY_ATTEMPTS)throw this.retryCount=0,t;return await new Promise(function(a){return setTimeout(a,i.RETRY_DELAY)}),this.fetchLatestScrobble()}}},{key:"handleAlbumCover",value:async function(t){return!t||i.LFM_DEFAULT_COVER_HASHES.some(function(a){return t.includes(a)})?null:t}},{key:"getLastError",value:function(){return this.lastError}},{key:"resetRetryCount",value:function(){this.retryCount=0}}],[{key:"getInstance",value:function(){return e.instance||(e.instance=new e),e.instance}}]),e}().getInstance();var z=function(e){return e[e.PLAYING=0]="PLAYING",e[e.STREAMING=1]="STREAMING",e[e.LISTENING=2]="LISTENING",e[e.COMPETING=5]="COMPETING",e}(z||{});const o=function(...e){return c.verboseLogging&&console.log("[Last.fm]",...e)},M=function(){function e(){P(this,e)}return U(e,[{key:"updateActivity",value:async function(){if(l.pluginStopped){o("Plugin is stopped, skipping update"),this.stopUpdates();return}o("Fetching last track...");try{if(!c.username||!c.apiKey)throw new Error("Username or API key not set");if(c.ignoreSpotify){if(K.findActivity(function(s){return s.sync_id})){o("Spotify is currently playing, clearing activity"),h("isSpotifyIgnored",!0),w();return}h("isSpotifyIgnored",!1)}const t=await F.fetchLatestScrobble();if(h("lastTrack",t),!t.nowPlaying){o("Last track is not currently playing"),w();return}if(l.lastTrackUrl===t.url){o("Track hasn't changed");return}const a={name:c.appName||i.DEFAULT_APP_NAME,flags:0,type:c.listeningTo?2:0,details:t.name,state:t.artist,status_display_type:1,application_id:i.APPLICATION_ID};if(a.name.includes("{{"))for(const s in t)a.name=a.name.replace(`{{${s}}}`,t[s]||"");if(c.showTimestamp&&(a.timestamps={start:Date.now()|0}),t.album){const s=await j([t.albumArt]);s[0]&&(a.assets={large_image:s[0],large_text:t.album})}o("Setting activity:",a),h("lastActivity",a),await D(a),l.lastTrackUrl=t.url,l.lastActivity=a,this.consecutiveFailures=0,o("Activity set successfully!")}catch(t){console.error("[Last.fm] Update error:",t),this.handleError(t)}}},{key:"handleError",value:function(t){this.consecutiveFailures++,h("lastError",t),this.consecutiveFailures>=i.MAX_RETRY_ATTEMPTS&&(o(`Failed ${this.consecutiveFailures} times, initiating reconnection...`),this.startReconnection())}},{key:"startReconnection",value:function(){var t=this;this.isReconnecting||(this.isReconnecting=!0,this.stopUpdates(),o("Starting reconnection process"),this.reconnectTimer=setInterval(function(){o("Attempting to reconnect..."),t.initialize().then(function(){o("Reconnection successful"),t.stopReconnection()}).catch(function(a){o("Reconnection failed:",a)})},i.RETRY_DELAY))}},{key:"stopReconnection",value:function(){this.reconnectTimer&&(clearInterval(this.reconnectTimer),this.reconnectTimer=void 0),this.isReconnecting=!1,this.consecutiveFailures=0}},{key:"stopUpdates",value:function(){this.updateTimer&&(clearInterval(this.updateTimer),this.updateTimer=void 0)}},{key:"initialize",value:async function(){var t=this;if(l.pluginStopped)throw new Error("Plugin is stopped");this.stopUpdates(),await this.updateActivity();const a=Math.max((Number(c.timeInterval)||i.DEFAULT_SETTINGS.timeInterval)*1e3,i.MIN_UPDATE_INTERVAL*1e3);this.updateTimer=setInterval(function(){return t.updateActivity()},a),o(`Update timer started with interval: ${a}ms`)}},{key:"stop",value:function(){l.pluginStopped=!0,this.stopUpdates(),this.stopReconnection(),w()}}],[{key:"getInstance",value:function(){return e.instance||(e.instance=new e),e.instance}}]),e}().getInstance(),G=function(){return M.initialize()},V=function(){return M.stop()},{FormText:$}=B.Forms,l={pluginStopped:!1,lastActivity:void 0,updateInterval:void 0,lastTrackUrl:void 0},x=i.DEFAULT_SETTINGS;for(const e in x)I.plugin.storage[e]=I.plugin.storage[e]??x[e];const c=new Proxy(I.plugin.storage,{get(e,t){return e[t]},set(e,t,a){return e[t]=a,!0}}),H=O.lazy(function(){return Promise.resolve().then(function(){return ne}).then(function(e){return{default:e.SettingsComponent}}).catch(function(e){return console.error("[Last.fm] Failed to load settings:",e),{default:function(){return n.React.createElement(A.ScrollView,{style:{flex:1},contentContainerStyle:{padding:16}},n.React.createElement($,{style:{color:"#ED4245"}},"Failed to load Last.fm settings. Please check your connection and reload Discord."))}}})});let _=0;const q=3,X=5e3;async function R(){try{await G(),_=0}catch(e){console.error("[Last.fm] Initialization error:",e),_++,_<q?(p.showToast("Retrying connection...",g.getAssetIDByName("ic_clock")),setTimeout(R,X)):p.showToast("Failed to connect to Last.fm",g.getAssetIDByName("Small"))}}var J={settings:function(){return n.React.createElement(n.React.Suspense,{fallback:n.React.createElement(A.View,{style:{flex:1,justifyContent:"center",alignItems:"center"}},n.React.createElement($,null,"Loading Last.fm settings..."))},n.React.createElement(H,null))},onLoad(){if(l.pluginStopped=!1,!c.username||!c.apiKey){p.showToast("Please configure Last.fm username and API key in settings",g.getAssetIDByName("ic_warning"));return}if(C.getCurrentUser())R();else{const e=function(){C.getCurrentUser()&&(R(),n.FluxDispatcher.unsubscribe("CONNECTION_OPEN",e))};n.FluxDispatcher.subscribe("CONNECTION_OPEN",e)}},onUnload(){l.pluginStopped=!0,V()},onSettingsUpdate(e){Object.assign(c,e),R()},onDiscordReconnect(){l.pluginStopped||R()}};const Q=[{version:"2.2.0",date:"2025-09-13",changes:["Remember kids! Do not sniff crack!"]},{version:"2.0.0",date:"2025-09-13",changes:["Fix settings scrolling"]},{version:"1.3.0",date:"2025-09-13",changes:["fix reanimated"]},{version:"1.2.0",date:"2025-09-13",changes:["test"]},{version:"1.1.0",date:"2025-09-12",changes:["fixed reanimated issue??"]}],W="2.2.0",{ScrollView:Z}=d.findByProps("ScrollView"),{TableRowGroup:y,TableSwitchRow:b,Stack:N,TableRow:u}=d.findByProps("TableSwitchRow","TableRowGroup","Stack","TableRow"),{TextInput:L}=d.findByProps("TextInput"),{FormText:ee}=d.findByProps("FormText"),f=function(e,t=""){return I.plugin.storage[e]??t},T=function(e,t){return I.plugin.storage[e]=t};function te(){const[e,t]=n.React.useReducer(function(r){return~r},0),a=function(){return t()},[s,E]=n.React.useState(!1),ae=async function(){const r=f("username"),S=f("apiKey");if(!r||!S){p.showToast("Please enter both username and API key",g.getAssetIDByName("Small"));return}E(!0);try{await F.fetchLatestScrobble(),p.showToast("Connection successful!",g.getAssetIDByName("Check")),await G()}catch(ie){p.showToast(`Connection failed: ${ie.message}`,g.getAssetIDByName("Small"))}finally{E(!1)}};return n.React.createElement(Z,{style:{flex:1},contentContainerStyle:{padding:10}},n.React.createElement(N,{spacing:8},n.React.createElement(y,{title:"Account Settings"},n.React.createElement(N,{spacing:4},n.React.createElement(L,{placeholder:"Last.fm Username",value:f("username"),onChange:function(r){T("username",r),a()},isClearable:!0}),n.React.createElement(L,{placeholder:"API Key",value:f("apiKey"),onChange:function(r){T("apiKey",r),a()},secureTextEntry:!0,isClearable:!0}),n.React.createElement(u,{label:"Get API Key",subLabel:"https://www.last.fm/api/account/create",onPress:function(){return A.Linking.openURL("https://www.last.fm/api/account/create")}})),n.React.createElement(u,{label:"Test Connection",trailing:s?n.React.createElement(u.Arrow,{loading:!0}):n.React.createElement(u.Arrow,null),onPress:ae,disabled:s})),n.React.createElement(y,{title:"Display Settings"},n.React.createElement(N,{spacing:4},n.React.createElement(L,{placeholder:`App Name (Default: ${i.DEFAULT_SETTINGS.appName})`,value:f("appName",i.DEFAULT_SETTINGS.appName),onChange:function(r){T("appName",r),a()},isClearable:!0}),n.React.createElement(L,{placeholder:`Update Interval (Default: ${i.DEFAULT_SETTINGS.timeInterval}s)`,value:String(f("timeInterval",i.DEFAULT_SETTINGS.timeInterval)),onChange:function(r){const S=Number(r);S>=i.MIN_UPDATE_INTERVAL?(T("timeInterval",S),a()):p.showToast(`Minimum interval is ${i.MIN_UPDATE_INTERVAL} seconds`,g.getAssetIDByName("Small"))},keyboardType:"numeric",isClearable:!0}))),n.React.createElement(y,{title:"Options"},n.React.createElement(b,{label:"Show 'Listening to' instead of 'Playing'",value:f("listeningTo",i.DEFAULT_SETTINGS.listeningTo),onValueChange:function(r){T("listeningTo",r),a()}}),n.React.createElement(b,{label:"Show Timestamp",value:f("showTimestamp",i.DEFAULT_SETTINGS.showTimestamp),onValueChange:function(r){T("showTimestamp",r),a()}}),n.React.createElement(b,{label:"Ignore when Spotify is playing",value:f("ignoreSpotify",i.DEFAULT_SETTINGS.ignoreSpotify),onValueChange:function(r){T("ignoreSpotify",r),a()}}),n.React.createElement(b,{label:"Verbose Logging",value:f("verboseLogging",i.DEFAULT_SETTINGS.verboseLogging),onValueChange:function(r){T("verboseLogging",r),a()}})),n.React.createElement(y,{title:"Plugin Status"},n.React.createElement(u,{label:"Status",subLabel:l.pluginStopped?"Stopped":"Running"}),n.React.createElement(u,{label:"Last Update",subLabel:l.lastTrackUrl?"Success":"No track data"})),n.React.createElement(y,{title:"About"},n.React.createElement(u,{label:"Version",subLabel:W}),n.React.createElement(u,{label:"View Changelog",trailing:n.React.createElement(u.Arrow,null),onPress:function(){A.Linking.openURL(i.GITHUB_COMMITS_URL)}})),n.React.createElement(y,{title:"Changelog"},Q.map(function(r,S){return n.React.createElement(u,{key:S,label:`v${r.version} (${r.date})`,subLabel:r.changes.join(", ")})}))))}var ne=Object.freeze({__proto__:null,settings:function(){return n.React.createElement(n.React.Suspense,{fallback:n.React.createElement(A.View,{style:{flex:1,justifyContent:"center",alignItems:"center"}},n.React.createElement(ee,null,"Loading Last.fm settings..."))},n.React.createElement(te,null))}});return m.currentSettings=c,m.default=J,m.pluginState=l,Object.defineProperty(m,"__esModule",{value:!0}),m})({},vendetta,vendetta.ui.assets,vendetta.ui.toasts,vendetta.metro.common,vendetta.metro.common.ReactNative,vendetta.metro,vendetta.ui.components,window.React);
|