From a16410bdb8c299292c3a1b20d55cedcdcea6456c Mon Sep 17 00:00:00 2001 From: kmmiio99o <164557248+kmmiio99o@users.noreply.github.com> Date: Fri, 19 Sep 2025 20:04:32 +0200 Subject: [PATCH] deploy --- .gitignore | 3 +++ Last.fm/index.js | 3 ++- Last.fm/manifest.json | 2 +- 3 files changed, 6 insertions(+), 2 deletions(-) create mode 100644 .gitignore diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..320c107 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +node_modules/ +dist/ +package-lock.json diff --git a/Last.fm/index.js b/Last.fm/index.js index 6add15e..94a2a70 100644 --- a/Last.fm/index.js +++ b/Last.fm/index.js @@ -1 +1,2 @@ -(function(g,n,y,D,o,S,_,h,m,v,E){"use strict";const c={DEFAULT_APP_NAME:"Music",DEFAULT_TIME_INTERVAL:5,APPLICATION_ID:"1054951789318909972",LFM_API_KEY:"014ffe8a614370f000d85d95ec30e1be",LFM_DEFAULT_COVER_HASHES:["2a96cbd8b46e442fc41c2b86b821562f","c6f59c1e5e7240a4c0d427abd71f3dbb"]};E.findByProps("SET_ACTIVITY");const F=E.findByProps("getAssetIds"),C=E.findByStoreName("SelfPresenceStore"),k=E.findByStoreName("UserStore");function p(){return w(null)}function w(e){r.pluginStopped&&(d(!0),e=null),r.lastActivity=e,n.FluxDispatcher.dispatch({type:"LOCAL_ACTIVITY_UPDATE",activity:e,pid:2312,socketId:"Last.fm@Vendetta"})}async function U(e,t=c.APPLICATION_ID){return e?await F.fetchAssetIds(t,e):[]}let R;const L={};function u(e,t){L[e]=t,R?.()}function M(){return[,R]=h.useReducer(function(e){return~e},0),JSON.stringify(L,null,4)}async function O(){const e=new URLSearchParams({method:"user.getrecenttracks",user:s.username,api_key:c.LFM_API_KEY,format:"json",limit:"1",extended:"1"}).toString(),t=await fetch(`https://ws.audioscrobbler.com/2.0/?${e}`);if(!t.ok)throw new Error(`Failed to fetch the latest scrobble: ${t.statusText}`);const a=await t.json(),l=a?.recenttracks?.track?.[0];if(u("lastAPIResponse",l),!l)throw a;return{name:l.name,artist:l.artist.name,album:l.album["#text"],albumArt:await V(l.image?.find(function(K){return K.size==="large"})?.["#text"]),url:l.url,date:l.date?.["#text"]??"now",nowPlaying:!!l["@attr"]?.nowplaying,loved:l.loved==="1"}}async function V(e){return c.LFM_DEFAULT_COVER_HASHES.some(function(t){return e.includes(t)})?null:e}var x=function(e){return e[e.PLAYING=0]="PLAYING",e[e.STREAMING=1]="STREAMING",e[e.LISTENING=2]="LISTENING",e[e.COMPETING=5]="COMPETING",e}(x||{});const i=function(...e){return s.verboseLogging&&console.log(...e)};async function P(){if(r.pluginStopped){i("--> Plugin is unloaded, aborting update()..."),d();return}if(i("--> Fetching last track..."),!s.username)throw _.showToast("Last.fm username is not set!",o.getAssetIDByName("Small")),d(),new Error("Username is not set");if(s.ignoreSpotify)if(C.findActivity(function(a){return a.sync_id})){i("--> Spotify is currently playing, aborting..."),u("isSpotifyIgnored",!0),p();return}else u("isSpotifyIgnored",!1);else u("isSpotifyIgnored",void 0);const e=await O().catch(async function(a){throw i("--> An error occurred while fetching the last track, aborting..."),p(),a});if(u("lastTrack",e),!e.nowPlaying){i("--> Last track is not currently playing, aborting..."),p();return}if(i("--> Track fetched!"),r.lastTrackUrl===e.url){i("--> Last track is the same as the previous one, aborting...");return}const t={name:s.appName||c.DEFAULT_APP_NAME,flags:0,type:s.listeningTo?2:0,details:e.name,state:`${e.artist}`,status_display_type:1,application_id:c.APPLICATION_ID};if(r.lastTrackUrl=e.url,t.name.includes("{{"))for(const a in e)t.name=t.name.replace(`{{${a}}}`,e[a]);if(s.showTimestamp&&(t.timestamps={start:Date.now()|0}),e.album){const a=await U([e.albumArt]);t.assets={large_image:a[0],large_text:`${e.album}`}}i("--> Setting activity..."),u("lastActivity",t),i(t);try{w(t)}catch(a){throw i("--> An error occurred while setting the activity"),p(),a}i("--> Successfully set activity!")}function d(e=!1){r.lastActivity=null,r.lastTrackUrl=null,r.updateInterval&&clearInterval(r.updateInterval),!e&&p()}async function b(){if(r.pluginStopped)throw new Error("Plugin is already stopped!");d();let e=0;await P().catch(function(t){console.error(t),e++}),r.updateInterval=setInterval(function(){return P().then(function(){e=0}).catch(function(t){console.error(t),++e>3&&(console.error("Failed to fetch/set activity 3 times, aborting..."),d())})},(Number(s.timeInterval)||c.DEFAULT_TIME_INTERVAL)*1e3)}const r={};v.plugin.storage.ignoreSpotify??=!0;const s={...v.plugin.storage};var B={settings:h.lazy(function(){return Promise.resolve().then(function(){return H})}),onLoad(){if(r.pluginStopped=!1,k.getCurrentUser())b().catch(console.error);else{const e=function(){b().catch(console.error),n.FluxDispatcher.unsubscribe(e)};n.FluxDispatcher.subscribe("CONNECTION_OPEN",e)}},onUnload(){r.pluginStopped=!0,d()}};const{FormRow:N,FormInput:I,FormDivider:f,FormSwitchRow:T,FormText:G,FormIcon:A}=S.Forms;function $(){async function e(){for(const t in y.storage)y.storage[t]!=null&&(s[t]=y.storage[t]);await b(),_.showToast("Settings updated!",o.getAssetIDByName("Check"))}return n.React.createElement(m.TouchableOpacity,{onPress:e},n.React.createElement(G,{style:{marginRight:12}},"UPDATE"))}var z=n.React.memo(function(){const e=D.useProxy(y.storage),t=n.NavigationNative.useNavigation();return h.useEffect(function(){t.setOptions({title:"Last.fm Configuration",headerRight:$})},[]),n.React.createElement(m.ScrollView,null,n.React.createElement(I,{value:e.appName||void 0,onChangeText:function(a){return e.appName=a.trim()},title:"Discord Application Name",placeholder:c.DEFAULT_APP_NAME,returnKeyType:"done"}),n.React.createElement(f,null),n.React.createElement(I,{required:!0,value:e.username||void 0,onChangeText:function(a){return e.username=a.trim()},title:"Last.fm username",helpText:!e.username&&n.React.createElement(m.Text,{style:{color:"#FF0000"}},"This field is required!"),placeholder:"wumpus123",returnKeyType:"done"}),n.React.createElement(f,null),n.React.createElement(I,{value:e.timeInterval,onChangeText:function(a){return e.timeInterval=a},title:"Update interval (in seconds)",placeholder:c.DEFAULT_TIME_INTERVAL.toString(),keyboardType:"numeric",returnKeyType:"done"}),n.React.createElement(f,null),n.React.createElement(T,{label:"Show time elapsed",subLabel:"Show the time elapsed since the song started playing",leading:n.React.createElement(A,{source:o.getAssetIDByName("clock")}),value:e.showTimestamp,onValueChange:function(a){return e.showTimestamp=a}}),n.React.createElement(f,null),n.React.createElement(T,{label:"Set status as listening",subLabel:'Set your status as "Listening to" instead of "Playing"',leading:n.React.createElement(A,{source:o.getAssetIDByName("ic_headset_neutral")}),value:e.listeningTo,onValueChange:function(a){return e.listeningTo=a}}),n.React.createElement(f,null),n.React.createElement(T,{label:"Hide when Spotify is running",subLabel:"Hide the status when a Spotify activity is detected",leading:n.React.createElement(A,{source:o.getAssetIDByName("img_account_sync_spotify_light_and_dark")}),value:e.ignoreSpotify,onValueChange:function(a){return e.ignoreSpotify=a}}),n.React.createElement(f,null),n.React.createElement(N,{label:"Debug",subLabel:"View debug information",leading:n.React.createElement(A,{source:o.getAssetIDByName("debug")}),trailing:N.Arrow,onPress:function(){t.push("VendettaCustomPage",{title:"Debug",render:h.lazy(function(){return Promise.resolve().then(function(){return j})})})}}))}),H=Object.freeze({__proto__:null,default:z});function Y(){const e=M();return React.createElement(m.ScrollView,null,React.createElement(S.Codeblock,{selectable:!0,style:{margin:12}},e))}var j=Object.freeze({__proto__:null,default:Y});return g.currentSettings=s,g.default=B,g.pluginState=r,Object.defineProperty(g,"__esModule",{value:!0}),g})({},vendetta.metro.common,vendetta.plugin,vendetta.storage,vendetta.ui.assets,vendetta.ui.components,vendetta.ui.toasts,window.React,vendetta.metro.common.ReactNative,vendetta,vendetta.metro); +(function(h,E,w,b,l,g,a,d,V,I){"use strict";const s={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 L(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function N(e,t){for(var n=0;ns.MAX_RETRY_ATTEMPTS)throw this.retryCount=0,t;return await new Promise(function(n){return setTimeout(n,s.RETRY_DELAY)}),this.fetchLatestScrobble()}}},{key:"handleAlbumCover",value:async function(t){return!t||s.LFM_DEFAULT_COVER_HASHES.some(function(n){return t.includes(n)})?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 Y=function(e){return e[e.PLAYING=0]="PLAYING",e[e.STREAMING=1]="STREAMING",e[e.LISTENING=2]="LISTENING",e[e.COMPETING=5]="COMPETING",e}(Y||{});const f=function(...e){return r.verboseLogging&&console.log("[Last.fm]",...e)},C=function(){function e(){L(this,e)}return P(e,[{key:"updateActivity",value:async function(){if(u.pluginStopped){f("Plugin is stopped, skipping update"),this.stopUpdates();return}f("Fetching last track...");try{if(!r.username||!r.apiKey)throw new Error("Username or API key not set");if(r.ignoreSpotify){if(O.findActivity(function(c){return c.sync_id})){f("Spotify is currently playing, clearing activity"),y("isSpotifyIgnored",!0),v();return}y("isSpotifyIgnored",!1)}const t=await D.fetchLatestScrobble();if(y("lastTrack",t),!t.nowPlaying){f("Last track is not currently playing"),v();return}if(u.lastTrackUrl===t.url){f("Track hasn't changed");return}const n={name:r.appName||s.DEFAULT_APP_NAME,flags:0,type:r.listeningTo?2:0,details:t.name,state:t.artist,status_display_type:1,application_id:s.APPLICATION_ID};if(n.name.includes("{{"))for(const c in t)n.name=n.name.replace(`{{${c}}}`,t[c]||"");if(r.showTimestamp&&(n.timestamps={start:Date.now()|0}),t.album){const c=await $([t.albumArt]);c[0]&&(n.assets={large_image:c[0],large_text:t.album})}f("Setting activity:",n),y("lastActivity",n),await U(n),u.lastTrackUrl=t.url,u.lastActivity=n,this.consecutiveFailures=0,f("Activity set successfully!")}catch(t){console.error("[Last.fm] Update error:",t),this.handleError(t)}}},{key:"handleError",value:function(t){this.consecutiveFailures++,y("lastError",t),this.consecutiveFailures>=s.MAX_RETRY_ATTEMPTS&&(f(`Failed ${this.consecutiveFailures} times, initiating reconnection...`),this.startReconnection())}},{key:"startReconnection",value:function(){var t=this;this.isReconnecting||(this.isReconnecting=!0,this.stopUpdates(),f("Starting reconnection process"),this.reconnectTimer=setInterval(function(){f("Attempting to reconnect..."),t.initialize().then(function(){f("Reconnection successful"),t.stopReconnection()}).catch(function(n){f("Reconnection failed:",n)})},s.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(u.pluginStopped)throw new Error("Plugin is stopped");this.stopUpdates(),await this.updateActivity();const n=Math.max((Number(r.timeInterval)||s.DEFAULT_SETTINGS.timeInterval)*1e3,s.MIN_UPDATE_INTERVAL*1e3);this.updateTimer=setInterval(function(){return t.updateActivity()},n),f(`Update timer started with interval: ${n}ms`)}},{key:"stop",value:function(){u.pluginStopped=!0,this.stopUpdates(),this.stopReconnection(),v()}}],[{key:"getInstance",value:function(){return e.instance||(e.instance=new e),e.instance}}]),e}().getInstance(),F=function(){return C.initialize()},M=function(){return C.stop()},{FormText:x}=w.Forms,u={pluginStopped:!1,lastActivity:void 0,updateInterval:void 0,lastTrackUrl:void 0},B=s.DEFAULT_SETTINGS;for(const e in B)E.plugin.storage[e]=E.plugin.storage[e]??B[e];const r=new Proxy(E.plugin.storage,{get(e,t){return e[t]},set(e,t,n){return e[t]=n,!0}}),K=V.lazy(function(){return Promise.resolve().then(function(){return W}).catch(function(e){return console.error("[Last.fm] Failed to load settings:",e),{default:function(){return a.React.createElement(d.ScrollView,{style:{flex:1},contentContainerStyle:{padding:16}},a.React.createElement(x,{style:{color:"#ED4245"}},"Failed to load Last.fm settings. Please check your connection and reload Discord."))}}})});let _=0;const H=3,z=5e3;async function m(){try{await F(),_=0}catch(e){console.error("[Last.fm] Initialization error:",e),_++,_=s.MIN_UPDATE_INTERVAL?n("timeInterval",p):g.showToast(`Minimum interval is ${s.MIN_UPDATE_INTERVAL} seconds`,l.getAssetIDByName("Small"))},keyboardType:"numeric"})),a.React.createElement(T,{title:"Options"},a.React.createElement(S,{label:"Show 'Listening to' instead of 'Playing'",icon:a.React.createElement(o.Icon,{source:l.getAssetIDByName("ic_music_24px")}),value:r.listeningTo??s.DEFAULT_SETTINGS.listeningTo,onValueChange:function(i){return n("listeningTo",i)}}),a.React.createElement(S,{label:"Unix Timestamp",icon:a.React.createElement(o.Icon,{source:l.getAssetIDByName("ic_timeline_24px")}),value:r.showTimestamp??s.DEFAULT_SETTINGS.showTimestamp,onValueChange:function(i){return n("showTimestamp",i)}}),a.React.createElement(S,{label:"Ignore when Spotify is playing",icon:a.React.createElement(o.Icon,{source:l.getAssetIDByName("ic_spotify_24px")}),value:r.ignoreSpotify??s.DEFAULT_SETTINGS.ignoreSpotify,onValueChange:function(i){return n("ignoreSpotify",i)}}),a.React.createElement(S,{label:"Verbose Logging",icon:a.React.createElement(o.Icon,{source:l.getAssetIDByName("ic_message_copy_24px")}),value:r.verboseLogging??s.DEFAULT_SETTINGS.verboseLogging,onValueChange:function(i){return n("verboseLogging",i)}})),a.React.createElement(T,{title:"Plugin Status"},a.React.createElement(o,{label:"Status",subLabel:u.pluginStopped?"Stopped":"Running"}),a.React.createElement(o,{label:"Last Update",subLabel:u.lastTrackUrl?"Success":"No track data"})),a.React.createElement(T,{title:"Changelog"},a.React.createElement(o,{label:"View GitHub Commits",icon:a.React.createElement(o.Icon,{source:l.getAssetIDByName("ic_history_24px")}),trailing:a.React.createElement(o.Arrow,null),onPress:function(){return d.Linking.openURL(s.GITHUB_COMMITS_URL)}}),q.map(function(i,p){return a.React.createElement(o,{key:p,label:`Version ${i.version}`,subLabel:i.date,onPress:function(){showConfirmationAlert({title:`Version ${i.version}`,content:i.changes.join(` +\u2022 `),confirmText:"OK",onConfirm:function(){},isDismissable:!0})}})})),a.React.createElement(d.View,{style:{padding:16,alignItems:"center"}},a.React.createElement(J,{style:{opacity:.5}},"Version ",X)))}var W=Object.freeze({__proto__:null,default:Q});return h.currentSettings=r,h.default=j,h.pluginState=u,Object.defineProperty(h,"__esModule",{value:!0}),h})({},vendetta,vendetta.ui.components,vendetta.storage,vendetta.ui.assets,vendetta.ui.toasts,vendetta.metro.common,vendetta.metro.common.ReactNative,window.React,vendetta.metro); diff --git a/Last.fm/manifest.json b/Last.fm/manifest.json index edf40cd..f29979f 100644 --- a/Last.fm/manifest.json +++ b/Last.fm/manifest.json @@ -1 +1 @@ -{"authors":[{"name":"pylix","id":"492949202121261067"}],"main":"index.js","name":"Last.fm","description":"Show off your last.fm status on your Discord profile.","vendetta":{"icon":"ic_stage_music"},"hash":"9ee1221b9446f6bc9aa6109e81660eae7b99d633c8b69c9c1fdc1b5107c1e585"} \ No newline at end of file +{"authors":[{"name":"pylix","id":"492949202121261067"},{"name":"kmmiio99o","id":"879393496627306587"}],"main":"index.js","name":"Last.fm","description":"Show off your last.fm status on your Discord profile.","vendetta":{"icon":"ic_stage_music"},"hash":"ba44f9ca12d5ddbc531deb4235942755773b89011cdf822fa6ba915011290945"} \ No newline at end of file