Main: add ESLint

This commit is contained in:
amsyarasyiq 2023-02-12 22:48:12 +08:00
parent b6d46a160a
commit 4ab72b8dd9
10 changed files with 96 additions and 35 deletions

41
.eslintrc.json Normal file
View file

@ -0,0 +1,41 @@
{
"env": {
"es2021": true,
"node": true
},
"extends": [
"eslint:recommended",
"plugin:react/recommended",
"plugin:@typescript-eslint/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": [
"react",
"@typescript-eslint"
],
"rules": {
"indent": [
"error",
4
],
"quotes": [
"error",
"double"
],
"semi": [
"error",
"always"
],
"@typescript-eslint/no-explicit-any": "off",
"@typescript-eslint/ban-ts-comment": "off",
"@typescript-eslint/triple-slash-reference": "off",
"eol-last": "error"
}
}

View file

@ -13,7 +13,13 @@ for (const plug of await readdir("./plugins")) {
try { try {
const bundle = await rollup({ const bundle = await rollup({
input: `./plugins/${plug}/${manifest.main}`, input: `./plugins/${plug}/${manifest.main}`,
onwarn: () => { }, onwarn: (warning) => {
![
"UNRESOLVED_IMPORT",
"MISSING_NAME_OPTION_FOR_IIFE_EXPORT",
"CIRCULAR_DEPENDENCY"
].includes(warning.code) && console.warn(warning);
},
plugins: [ plugins: [
nodeResolve(), nodeResolve(),
commonjs(), commonjs(),

View file

@ -1,13 +1,21 @@
{ {
"scripts": { "scripts": {
"build": "node build.mjs" "build": "node build.mjs",
"lint": "eslint plugins"
}, },
"devDependencies": { "devDependencies": {
"@rollup/plugin-commonjs": "^24.0.1", "@rollup/plugin-commonjs": "^24.0.1",
"@rollup/plugin-eslint": "^9.0.3",
"@rollup/plugin-node-resolve": "^15.0.1", "@rollup/plugin-node-resolve": "^15.0.1",
"@rollup/plugin-typescript": "^11.0.0",
"@typescript-eslint/eslint-plugin": "^5.51.0",
"@typescript-eslint/parser": "^5.51.0",
"esbuild": "^0.16.17", "esbuild": "^0.16.17",
"eslint": "^8.34.0",
"eslint-plugin-react": "^7.32.2",
"rollup": "^3.15.0", "rollup": "^3.15.0",
"rollup-plugin-esbuild": "^5.0.0", "rollup-plugin-esbuild": "^5.0.0",
"typescript": "^4.9.5",
"vendetta-types": "^2.3.4" "vendetta-types": "^2.3.4"
} }
} }

View file

@ -1,7 +1,7 @@
import { logger } from "@vendetta"; import { logger } from "@vendetta";
import { findByDisplayName } from "@vendetta/metro"; import { findByDisplayName } from "@vendetta/metro";
let origState: Boolean; let origState: boolean;
const ChatInput = findByDisplayName("ChatInput"); const ChatInput = findByDisplayName("ChatInput");
export default { export default {
@ -14,4 +14,4 @@ export default {
logger.log("Unloading HideGiftButton.."); logger.log("Unloading HideGiftButton..");
ChatInput.defaultProps.hideGiftButton = origState; ChatInput.defaultProps.hideGiftButton = origState;
} }
} };

View file

@ -1,23 +1,23 @@
import { plugin } from "@vendetta"; import { plugin } from "@vendetta";
import { findByProps, findByStoreName } from '@vendetta/metro'; import { findByProps, findByStoreName } from "@vendetta/metro";
import { FluxDispatcher } from '@vendetta/metro/common'; import { FluxDispatcher } from "@vendetta/metro/common";
import Settings from "./Settings"; import Settings from "./Settings";
import { flush, initialize, patchActivityType } from "./utils"; import { flush, initialize, patchActivityType } from "./utils";
export const global = {} as { export const global = {} as {
stopped?: Boolean, stopped?: boolean,
lastActivity?: Activity, lastActivity?: Activity,
updateInterval?: NodeJS.Timer, updateInterval?: NodeJS.Timer,
lastTrackUrl?: string, lastTrackUrl?: string,
activityTypeUnpatch?: () => boolean activityTypeUnpatch?: () => boolean
} };
export const currentSettings = { ...plugin.storage } as PluginSettings; export const currentSettings = { ...plugin.storage } as PluginSettings;
// Discord modules that we need // Discord modules that we need
export const UserStore = findByStoreName("UserStore") export const UserStore = findByStoreName("UserStore");
export const SET_ACTIVITY = findByProps('SET_ACTIVITY').SET_ACTIVITY; export const SET_ACTIVITY = findByProps("SET_ACTIVITY").SET_ACTIVITY;
export const verboseLog = (...message: any) => currentSettings.verboseLogging && console.log(...message); export const verboseLog = (...message: any) => currentSettings.verboseLogging && console.log(...message);
@ -47,4 +47,4 @@ export default {
global.activityTypeUnpatch = null; global.activityTypeUnpatch = null;
}, },
settings: Settings settings: Settings
} };

View file

@ -3,13 +3,14 @@ import { storage } from "@vendetta/plugin";
import { useProxy } from "@vendetta/storage"; import { useProxy } from "@vendetta/storage";
import { getAssetIDByName } from "@vendetta/ui/assets"; import { getAssetIDByName } from "@vendetta/ui/assets";
import { Forms } from "@vendetta/ui/components"; import { Forms } from "@vendetta/ui/components";
import { showToast } from "@vendetta/ui/toasts";
import { currentSettings } from "."; import { currentSettings } from ".";
import Constants from "./constants"; import Constants from "./constants";
import { flush, initialize } from "./utils"; import { flush, initialize } from "./utils";
const { ScrollView, TouchableOpacity, Text } = ReactNative; const { ScrollView, TouchableOpacity, Text } = ReactNative;
const { FormInput, FormDivider, FormSwitchRow, FormText, FormIcon, FormTextColors } = Forms; const { FormInput, FormDivider, FormSwitchRow, FormText, FormIcon } = Forms;
export default function Settings() { export default function Settings() {
const settings = useProxy(storage) as PluginSettings; const settings = useProxy(storage) as PluginSettings;
@ -17,8 +18,8 @@ export default function Settings() {
React.useEffect(() => { React.useEffect(() => {
navigation.setOptions({ navigation.setOptions({
headerRight: () => ( headerRight: () => {
<TouchableOpacity onPress={() => { async function onPressCallback() {
for (const key in storage) { for (const key in storage) {
if (typeof storage[key] === "boolean" || storage[key]) { if (typeof storage[key] === "boolean" || storage[key]) {
currentSettings[key] = settings[key]; currentSettings[key] = settings[key];
@ -26,11 +27,15 @@ export default function Settings() {
} }
console.log("Applying settings..."); console.log("Applying settings...");
flush().then(() => initialize()); await flush();
}}> await initialize();
<FormText style={{ marginRight: 12 }}>UPDATE</FormText> showToast("Settings updated!", getAssetIDByName("Check"));
</TouchableOpacity> }
)
return <TouchableOpacity onPress={onPressCallback}>
<FormText style={{ marginRight: 12 }}>{"UPDATE"}</FormText>
</TouchableOpacity>;
}
}); });
}, []); }, []);
@ -77,5 +82,5 @@ export default function Settings() {
onValueChange={(value: boolean) => settings.verboseLogging = value} onValueChange={(value: boolean) => settings.verboseLogging = value}
/> />
</ScrollView> </ScrollView>
) );
} }

View file

@ -1,3 +1,4 @@
/* eslint-disable @typescript-eslint/no-unused-vars */
type PluginSettings = { type PluginSettings = {
/** Application's name */ /** Application's name */
appName: string; appName: string;

View file

@ -8,12 +8,12 @@ import Constants from "./constants";
/** Fetches the latest user's scrobble */ /** Fetches the latest user's scrobble */
async function fetchLatestScrobble(): Promise<Track> { async function fetchLatestScrobble(): Promise<Track> {
const params = new URLSearchParams({ const params = new URLSearchParams({
'method': 'user.getrecenttracks', "method": "user.getrecenttracks",
'user': currentSettings.username, "user": currentSettings.username,
'api_key': Constants.LFM_API_KEY, "api_key": Constants.LFM_API_KEY,
'format': 'json', "format": "json",
'limit': '1', "limit": "1",
'extended': '1' "extended": "1"
}).toString(); }).toString();
const info = await fetch(`https://ws.audioscrobbler.com/2.0/?${params}`).then(x => { const info = await fetch(`https://ws.audioscrobbler.com/2.0/?${params}`).then(x => {
@ -24,12 +24,12 @@ async function fetchLatestScrobble(): Promise<Track> {
return { return {
name: lastTrack.name, name: lastTrack.name,
artist: lastTrack.artist.name, artist: lastTrack.artist.name,
album: lastTrack.album['#text'], album: lastTrack.album["#text"],
albumArt: handleAlbumCover(lastTrack.image[3]['#text']), albumArt: handleAlbumCover(lastTrack.image[3]["#text"]),
url: lastTrack.url, url: lastTrack.url,
date: lastTrack.date?.['#text'] ?? 'now', date: lastTrack.date?.["#text"] ?? "now",
nowPlaying: Boolean(lastTrack['@attr']?.nowplaying), nowPlaying: Boolean(lastTrack["@attr"]?.nowplaying),
loved: lastTrack.loved === '1', loved: lastTrack.loved === "1",
} as Track; } as Track;
} }
@ -129,7 +129,7 @@ export async function update() {
activity.assets = { activity.assets = {
large_image: lastTrack.albumArt, large_image: lastTrack.albumArt,
large_text: `on ${lastTrack.album}` large_text: `on ${lastTrack.album}`
} };
} }
const response = await sendRequest(activity).catch(async function (err) { const response = await sendRequest(activity).catch(async function (err) {

View file

@ -46,7 +46,7 @@ export default {
logger.error("Failed to start call", e); logger.error("Failed to start call", e);
} }
}, },
}) });
}); });
} }
} };

View file

@ -17,4 +17,4 @@ export default {
logger.log("Disabling NoIdle.."); logger.log("Disabling NoIdle..");
unpatch?.(); unpatch?.();
} }
} };