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