vd-plugins/Last.fm/index.js
2023-02-27 18:03:37 +00:00

2 lines
No EOL
8.4 KiB
JavaScript

(function(exports,_vendetta,metro,common,plugin,storage,assets,components,toasts){'use strict';const Constants={DEFAULT_APP_NAME:"Music",DEFAULT_TIME_INTERVAL:5,APPLICATION_ID:"1054951789318909972",LFM_API_KEY:"615322f0047e12aedbc610d9d71f7430",LFM_DEFAULT_COVER_HASHES:["2a96cbd8b46e442fc41c2b86b821562f","c6f59c1e5e7240a4c0d427abd71f3dbb"]};const AssetManager=metro.findByProps("getAssetIds");async function fetchLatestScrobble(){const params=new URLSearchParams({"method":"user.getrecenttracks","user":currentSettings.username,"api_key":Constants.LFM_API_KEY,"format":"json","limit":"1","extended":"1"}).toString();const result=await fetch(`https://ws.audioscrobbler.com/2.0/?${params}`);if(!result.ok)throw new Error(`Failed to fetch the latest scrobble: ${result.statusText}`);const info=await result.json();const lastTrack=info?.recenttracks?.track?.[0];if(!lastTrack)throw info;return {name:lastTrack.name,artist:lastTrack.artist.name,album:lastTrack.album["#text"],albumArt:await handleAlbumCover(lastTrack.image[3]["#text"]),url:lastTrack.url,date:lastTrack.date?.["#text"]??"now",nowPlaying:Boolean(lastTrack["@attr"]?.nowplaying),loved:lastTrack.loved==="1"}}async function handleAlbumCover(cover){if(Constants.LFM_DEFAULT_COVER_HASHES.some(function(x){return cover.includes(x)})){return null}return cover}function clearActivity(){global.lastActivity&&verboseLog("--> Clearing activity...");return sendRequest(null)}function sendRequest(activity){if(global.pluginStopped){console.log("--> Plugin is unloaded, aborting...");global.updateInterval&&clearInterval(global.updateInterval);activity=null;}global.lastActivity=activity;common.FluxDispatcher.dispatch({type:"LOCAL_ACTIVITY_UPDATE",activity:activity});}async function fetchAsset(asset){let appId=arguments.length>1&&arguments[1]!==void 0?arguments[1]:Constants.APPLICATION_ID;if(!asset)return null;if(typeof asset==="string"){const assetId=await AssetManager.getAssetIds(appId,[asset]);return assetId[0]}return await AssetManager.getAssetIds(appId,asset)}async function update(){verboseLog("--> Fetching last track...");if(!currentSettings.username){toasts.showToast("Last.fm username is not set!",assets.getAssetIDByName("Small"));flush();throw new Error("Username is not set")}const lastTrack=await fetchLatestScrobble().catch(async function(err){verboseLog("--> An error occurred while fetching the last track, aborting...");clearActivity();throw err});if(!lastTrack.nowPlaying){verboseLog("--> Last track is not currently playing, aborting...");clearActivity();return}verboseLog("--> Track fetched!");if(global.lastTrackUrl===lastTrack.url){verboseLog("--> Last track is the same as the previous one, aborting...");return}const activity={name:currentSettings.appName||Constants.DEFAULT_APP_NAME,flags:0,type:currentSettings.listeningTo?2:0,details:lastTrack.name,state:`by ${lastTrack.artist}`,application_id:Constants.APPLICATION_ID};global.lastTrackUrl=lastTrack.url;if(activity.name.includes("{{")){for(const key in lastTrack){activity.name=activity.name.replace(`{{${key}}}`,lastTrack[key]);}}if(currentSettings.showTimestamp){activity.timestamps={start:Date.now()/1e3|0};}if(lastTrack.album){activity.assets={large_image:await fetchAsset(lastTrack.albumArt),large_text:`on ${lastTrack.album}`};}verboseLog("--> Setting activity...");verboseLog(activity);try{sendRequest(activity);}catch(err){verboseLog("--> An error occurred while setting the activity");clearActivity();throw err}verboseLog("--> Successfully set activity!");}function flush(){console.log("--> Flushing...");global.lastActivity=null;global.lastTrackUrl=null;global.updateInterval&&clearInterval(global.updateInterval);clearActivity();}async function initialize(){console.log("--> Initializing...");if(global.pluginStopped){throw new Error("Plugin is already stopped!")}flush();let tries=0;await update().catch(function(err){console.error(err);tries++;});global.updateInterval=setInterval(function(){return update().then(function(){tries=0;}).catch(function(err){console.error(err);if(++tries>3){console.error("Failed to fetch/set activity 3 times, aborting...");flush();}})},(currentSettings.timeInterval||Constants.DEFAULT_TIME_INTERVAL)*1e3);}
const{ScrollView,TouchableOpacity,Text}=common.ReactNative;const{FormInput,FormDivider,FormSwitchRow,FormText,FormIcon}=components.Forms;function UpdateButton(){async function onPressCallback(){for(const key in plugin.storage){if(plugin.storage[key]===false||plugin.storage[key]){currentSettings[key]=plugin.storage[key];}}console.log("Applying settings...");await initialize();toasts.showToast("Settings updated!",assets.getAssetIDByName("Check"));}return common.React.createElement(TouchableOpacity,{onPress:onPressCallback},common.React.createElement(FormText,{style:{marginRight:12}},"UPDATE"))}function Settings(){const settings=storage.useProxy(plugin.storage);const navigation=common.NavigationNative.useNavigation();common.React.useEffect(function(){navigation.setOptions({title:"Last.fm Configuration",headerRight:UpdateButton});},[]);return common.React.createElement(ScrollView,null,common.React.createElement(FormInput,{value:settings.appName||undefined,onChangeText:function(value){return settings.appName=value.trim()},title:"Discord Application Name",placeholder:Constants.DEFAULT_APP_NAME,returnKeyType:"done"}),common.React.createElement(FormDivider,null),common.React.createElement(FormInput,{required:true,value:settings.username||undefined,onChangeText:function(value){return settings.username=value.trim()},title:"Last.fm username",helpText:!settings.username&&common.React.createElement(Text,{style:{color:"#FF0000"}},"This field is required!"),placeholder:"wumpus123",returnKeyType:"done"}),common.React.createElement(FormDivider,null),common.React.createElement(FormInput,{value:settings.timeInterval,onChangeText:function(value){return settings.timeInterval=Number(value)},title:"Update interval (in seconds)",placeholder:Constants.DEFAULT_TIME_INTERVAL.toString(),keyboardType:"numeric",returnKeyType:"done"}),common.React.createElement(FormDivider,null),common.React.createElement(FormSwitchRow,{label:"Show time elapsed",subLabel:"Show the time elapsed since the song started playing",leading:common.React.createElement(FormIcon,{source:assets.getAssetIDByName("clock")}),value:settings.showTimestamp,onValueChange:function(value){return settings.showTimestamp=value}}),common.React.createElement(FormDivider,null),common.React.createElement(FormSwitchRow,{label:"Set status as listening",subLabel:'Set your status as "Listening to" instead of "Playing"',leading:common.React.createElement(FormIcon,{source:assets.getAssetIDByName("ic_headset_neutral")}),value:settings.listeningTo,onValueChange:function(value){return settings.listeningTo=value}}),common.React.createElement(FormDivider,null),common.React.createElement(FormSwitchRow,{label:"Verbose logging",subLabel:"Log more information to the console for debugging purposes",leading:common.React.createElement(FormIcon,{source:assets.getAssetIDByName("pencil")}),value:settings.verboseLogging,onValueChange:function(value){return settings.verboseLogging=value}}))}function _classCallCheck(instance,Constructor){if(!(instance instanceof Constructor)){throw new TypeError("Cannot call a class as a function")}}const global={};const currentSettings={..._vendetta.plugin.storage};const UserStore=metro.findByStoreName("UserStore");const SET_ACTIVITY=metro.findByProps("SET_ACTIVITY").SET_ACTIVITY;const verboseLog=function(){for(var _len=arguments.length,message=new Array(_len),_key=0;_key<_len;_key++){message[_key]=arguments[_key];}return currentSettings.verboseLogging&&console.log(...message)};var index = new(function(){function LastFM(){_classCallCheck(this,LastFM);this.settings=Settings;}var _proto=LastFM.prototype;_proto.onLoad=function onLoad(){console.log("Starting last.fm plugin..");global.pluginStopped=false;if(UserStore.getCurrentUser()){console.log("User is already logged in, initializing...");initialize().catch(console.error);}common.FluxDispatcher.subscribe("CONNECTION_OPEN",function(){initialize().catch(console.error);});};_proto.onUnload=function onUnload(){console.log("Stopping last.fm...");global.pluginStopped=true;flush();};return LastFM}());exports.SET_ACTIVITY=SET_ACTIVITY;exports.UserStore=UserStore;exports.currentSettings=currentSettings;exports.default=index;exports.global=global;exports.verboseLog=verboseLog;Object.defineProperty(exports,'__esModule',{value:true});return exports;})({},vendetta,vendetta.metro,vendetta.metro.common,vendetta.plugin,vendetta.storage,vendetta.ui.assets,vendetta.ui.components,vendetta.ui.toasts);