refactor: ♻️ Fix linter errors

This commit is contained in:
Jesse Wierzbinski 2024-06-19 14:07:56 -10:00
parent 8a984abfb2
commit f9433e259b
No known key found for this signature in database
30 changed files with 235 additions and 157 deletions

View file

@ -1,5 +1,5 @@
{
"$schema": "https://biomejs.dev/schemas/1.6.4/schema.json",
"$schema": "https://biomejs.dev/schemas/1.8.1/schema.json",
"organizeImports": {
"enabled": true,
"ignore": ["node_modules/**/*", "dist/**/*", ".output", ".nuxt"]
@ -7,7 +7,65 @@
"linter": {
"enabled": true,
"rules": {
"recommended": true
"all": true,
"correctness": {
"noNodejsModules": "off",
"noUndeclaredVariables": "off",
"useHookAtTopLevel": "off",
"noUnusedVariables": "off",
"noUnusedImports": "off"
},
"complexity": {
"noExcessiveCognitiveComplexity": "off"
},
"style": {
"noDefaultExport": "off",
"noParameterProperties": "off",
"noNamespaceImport": "off",
"useFilenamingConvention": "off",
"useNamingConvention": {
"level": "warn",
"options": {
"requireAscii": false,
"strictCase": false,
"conventions": [
{
"selector": {
"kind": "typeProperty"
},
"formats": [
"camelCase",
"CONSTANT_CASE",
"PascalCase",
"snake_case"
]
},
{
"selector": {
"kind": "objectLiteralProperty",
"scope": "any"
},
"formats": [
"camelCase",
"CONSTANT_CASE",
"PascalCase",
"snake_case"
]
}
]
}
}
},
"nursery": {
"noDuplicateElseIf": "warn",
"noDuplicateJsonKeys": "warn",
"noEvolvingTypes": "warn",
"noYodaExpression": "warn",
"useConsistentBuiltinInstantiation": "warn",
"useErrorMessage": "warn",
"useImportExtensions": "off",
"useThrowNewError": "warn"
}
},
"ignore": ["node_modules/**/*", "dist/**/*", ".output", ".nuxt"]
},

View file

@ -121,15 +121,17 @@ onMounted(() => {
useListen("composer:reply", (note: Status) => {
respondingTo.value = note;
respondingType.value = "reply";
if (note.account.id !== identity.value?.account.id)
if (note.account.id !== identity.value?.account.id) {
content.value = `@${note.account.acct} `;
}
});
useListen("composer:quote", (note: Status) => {
respondingTo.value = note;
respondingType.value = "quote";
if (note.account.id !== identity.value?.account.id)
if (note.account.id !== identity.value?.account.id) {
content.value = `@${note.account.acct} `;
}
});
useListen("composer:edit", async (note: Status) => {
@ -176,7 +178,7 @@ const client = useClient();
const send = async () => {
loading.value = true;
if (!identity.value || !client.value) {
if (!(identity.value && client.value)) {
throw new Error("Not authenticated");
}

View file

@ -25,8 +25,9 @@ const { Tab, ArrowRight, ArrowLeft, Enter } = useMagicKeys({
if (
["Tab", "Enter", "ArrowRight", "ArrowLeft"].includes(e.key) &&
topEmojis.value !== null
)
) {
e.preventDefault();
}
},
});
const identity = useCurrentIdentity();
@ -34,9 +35,11 @@ const topEmojis = ref<Emoji[] | null>(null);
const selectedEmojiIndex = ref<number | null>(null);
watchEffect(() => {
if (!identity.value) return;
if (!identity.value) {
return;
}
if (props.currentlyTypingEmoji !== null)
if (props.currentlyTypingEmoji !== null) {
topEmojis.value = identity.value.emojis
.map((emoji) => ({
...emoji,
@ -47,7 +50,9 @@ watchEffect(() => {
}))
.sort((a, b) => a.distance - b.distance)
.slice(0, 20);
else topEmojis.value = null;
} else {
topEmojis.value = null;
}
if (ArrowRight?.value && topEmojis.value !== null) {
selectedEmojiIndex.value = (selectedEmojiIndex.value ?? -1) + 1;
@ -74,7 +79,9 @@ watchEffect(() => {
if ((Tab?.value || Enter?.value) && topEmojis.value !== null) {
const emoji = topEmojis.value[selectedEmojiIndex.value ?? 0];
if (emoji) emit("autocomplete", emoji.shortcode);
if (emoji) {
emit("autocomplete", emoji.shortcode);
}
}
});

View file

@ -104,7 +104,9 @@ watch(
files,
(newFiles) => {
for (const data of newFiles) {
if (data.progress === 0) uploadFile(data.file);
if (data.progress === 0) {
uploadFile(data.file);
}
}
},
{
@ -137,14 +139,22 @@ const updateAltText = (id: string, altText?: string) => {
};
const getIcon = (mimeType: string) => {
if (mimeType.startsWith("image/")) return "tabler:photo";
if (mimeType.startsWith("video/")) return "tabler:video";
if (mimeType.startsWith("audio/")) return "tabler:music";
if (mimeType.startsWith("image/")) {
return "tabler:photo";
}
if (mimeType.startsWith("video/")) {
return "tabler:video";
}
if (mimeType.startsWith("audio/")) {
return "tabler:music";
}
return "tabler:file";
};
const formatBytes = (bytes: number) => {
if (bytes === 0) return "0 Bytes";
if (bytes === 0) {
return "0 Bytes";
}
const k = 1000;
const dm = 2;
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];

View file

@ -24,8 +24,9 @@ const { Tab, ArrowRight, ArrowLeft, Enter } = useMagicKeys({
if (
["Tab", "Enter", "ArrowRight", "ArrowLeft"].includes(e.key) &&
topUsers.value !== null
)
) {
e.preventDefault();
}
},
});
const topUsers = ref<Account[] | null>(null);
@ -79,7 +80,9 @@ watch(
if ((Tab?.value || Enter?.value) && topUsers.value !== null) {
const user = topUsers.value[selectedUserIndex.value ?? 0];
if (user) emit("autocomplete", user.username);
if (user) {
emit("autocomplete", user.username);
}
}
},
);

View file

@ -50,7 +50,9 @@ useListen("note:edit", async (note) => {
useEvent("composer:edit", note);
});
useListen("composer:open", () => {
if (identity.value) open.value = true;
if (identity.value) {
open.value = true;
}
});
useListen("composer:close", () => {
open.value = false;

View file

@ -104,7 +104,9 @@ const save = async () => {
type: "success",
});
if (identity.value) identity.value.account = data;
if (identity.value) {
identity.value.account = data;
}
} catch (e) {
const error = e as ResponseError<{ error: string }>;

View file

@ -187,7 +187,7 @@ const signIn = async () => {
const signOut = async (id?: string) => {
loadingAuth.value = true;
if (!appData.value || !identity.value) {
if (!(appData.value && identity.value)) {
console.error("No app or identity data to sign out");
return;
}
@ -208,7 +208,9 @@ const signOut = async (id?: string) => {
identityToRevoke.tokens.access_token,
identityToRevoke.tokens.access_token,
)
.catch(() => {});
.catch(() => {
// Do nothing
});
if (id === identity.value.id) {
identity.value = null;

View file

@ -41,10 +41,11 @@ const calculatedWidth = computed(
const getWidth = (index: number, lines: number) => {
if (isWidthSpecified.value) {
if (isContent.value)
if (isContent.value) {
return index === lines
? `${calculatedWidth.value}${props.widthUnit}`
: "100%";
}
return `${calculatedWidth.value}${props.widthUnit}`;
}
return undefined;

View file

@ -50,7 +50,9 @@ const openLightbox = () => {
};
const formatBytes = (bytes: number) => {
if (bytes === 0) return "0 Bytes";
if (bytes === 0) {
return "0 Bytes";
}
const k = 1000;
const dm = 2;
const sizes = ["Bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"];

View file

@ -206,7 +206,9 @@ const numberFormat = (number = 0) =>
}).format(number);
const likeFn = async () => {
if (!outputtedNote.value) return;
if (!outputtedNote.value) {
return;
}
if (outputtedNote.value.favourited) {
const output = await client.value.unfavouriteStatus(
outputtedNote.value.id,
@ -227,7 +229,9 @@ const likeFn = async () => {
};
const reblogFn = async () => {
if (!outputtedNote.value) return;
if (!outputtedNote.value) {
return;
}
if (outputtedNote.value?.reblogged) {
const output = await client.value.unreblogStatus(
outputtedNote.value.id,

View file

@ -43,7 +43,9 @@ const { relationship } = useRelationship(
);
const acceptFollowRequest = async () => {
if (!props.notification?.account) return;
if (!props.notification?.account) {
return;
}
isWorkingOnFollowRequest.value = true;
const { data } = await client.value.acceptFollowRequest(
props.notification.account.id,
@ -53,7 +55,9 @@ const acceptFollowRequest = async () => {
};
const rejectFollowRequest = async () => {
if (!props.notification?.account) return;
if (!props.notification?.account) {
return;
}
isWorkingOnFollowRequest.value = true;
const { data } = await client.value.rejectFollowRequest(
props.notification.account.id,
@ -69,7 +73,9 @@ const { display_name } = useParsedAccount(
);
const text = computed(() => {
if (!props.notification) return "";
if (!props.notification) {
return "";
}
switch (props.notification.type) {
case "mention":
@ -82,13 +88,16 @@ const text = computed(() => {
return "followed you";
case "follow_request":
return "requested to follow you";
default:
default: {
console.error("Unknown notification type", props.notification.type);
return "";
}
}
});
const icon = computed(() => {
if (!props.notification) return "";
if (!props.notification) {
return "";
}
switch (props.notification.type) {
case "mention":

View file

@ -112,7 +112,9 @@ const accountId = computed(() => props.account?.id ?? null);
const { relationship, isLoading } = useRelationship(client, accountId);
const follow = () => {
if (!identity.value || !props.account || !relationship.value) return;
if (!(identity.value && props.account && relationship.value)) {
return;
}
relationship.value = {
...relationship.value,
following: true,
@ -120,7 +122,9 @@ const follow = () => {
};
const unfollow = () => {
if (!identity.value || !props.account || !relationship.value) return;
if (!(identity.value && props.account && relationship.value)) {
return;
}
relationship.value = {
...relationship.value,
following: false,

View file

@ -52,7 +52,9 @@ watch(
() => props.timeline,
(newTimeline, oldTimeline) => {
// If posts are deleted, don't start loading more posts
if (newTimeline.length === oldTimeline.length - 1) return;
if (newTimeline.length === oldTimeline.length - 1) {
return;
}
isLoading.value = false;
// If less than NOTES_PER_PAGE statuses are returned, we have reached the end
if (

View file

@ -12,12 +12,13 @@ export const useAccount = (
const output = ref(null as Account | null);
watchEffect(() => {
if (toValue(accountId))
if (toValue(accountId)) {
toValue(client)
?.getAccount(toValue(accountId) ?? "")
.then((res) => {
output.value = res.data;
});
}
});
return output;

View file

@ -3,7 +3,9 @@ import type { RolePermission } from "@lysand-org/client/types";
import { useCurrentIdentity } from "./Identities";
export const useCacheRefresh = (client: MaybeRef<LysandClient | null>) => {
if (import.meta.server) return;
if (import.meta.server) {
return;
}
const identity = useCurrentIdentity();
@ -14,7 +16,9 @@ export const useCacheRefresh = (client: MaybeRef<LysandClient | null>) => {
toValue(client)
?.verifyAccountCredentials()
.then((res) => {
if (identity.value) identity.value.account = res.data;
if (identity.value) {
identity.value.account = res.data;
}
})
.catch((err) => {
const code = err.response.status;
@ -34,7 +38,9 @@ export const useCacheRefresh = (client: MaybeRef<LysandClient | null>) => {
toValue(client)
?.getInstanceCustomEmojis()
.then((res) => {
if (identity.value) identity.value.emojis = res.data;
if (identity.value) {
identity.value.emojis = res.data;
}
});
toValue(client)
@ -47,16 +53,19 @@ export const useCacheRefresh = (client: MaybeRef<LysandClient | null>) => {
.flatMap((r) => r.permissions)
.filter((p, i, arr) => arr.indexOf(p) === i);
if (identity.value)
if (identity.value) {
identity.value.permissions =
permissions as unknown as RolePermission[];
}
});
}
toValue(client)
?.getInstance()
.then((res) => {
if (identity.value) identity.value.instance = res.data;
if (identity.value) {
identity.value.instance = res.data;
}
});
});
};

View file

@ -45,12 +45,15 @@ export const useCurrentIdentity = (): Ref<Identity | null> => {
if (newCurrent) {
currentId.value = newCurrent.id;
// If the identity is updated, update the identity in the list
if (identities.value.find((i) => i.id === newCurrent.id))
if (identities.value.find((i) => i.id === newCurrent.id)) {
identities.value = identities.value.map((i) =>
i.id === newCurrent.id ? newCurrent : i,
);
}
// If the identity is not in the list, add it
else identities.value.push(newCurrent);
else {
identities.value.push(newCurrent);
}
// Force update the identities
identities.value = [...identities.value];

View file

@ -3,84 +3,21 @@ import type { Status } from "@lysand-org/client/types";
export const useLocalTimeline = (
client: LysandClient | null,
options: MaybeRef<
Partial<{
options: MaybeRef<{
only_media: boolean;
max_id: string;
since_id: string;
min_id: string;
limit: number;
}>
>,
}>,
): {
timeline: Ref<Status[]>;
loadNext: () => Promise<void>;
loadPrev: () => Promise<void>;
} => {
if (!client) {
return {
timeline: ref([]),
loadNext: async () => {},
loadPrev: async () => {},
};
}
const fetchedNotes = ref<Status[]>([]);
const fetchedNoteIds = new Set<string>();
let nextMaxId: string | undefined = undefined;
let prevMinId: string | undefined = undefined;
const loadNext = async () => {
const response = await client.getLocalTimeline({
...ref(options).value,
max_id: nextMaxId,
limit: useConfig().NOTES_PER_PAGE,
});
const newNotes = response.data.filter(
(note) => !fetchedNoteIds.has(note.id),
return useTimeline(
client,
(client, options) => client?.getLocalTimeline(options),
options,
);
if (newNotes.length > 0) {
fetchedNotes.value = [...fetchedNotes.value, ...newNotes];
nextMaxId = newNotes[newNotes.length - 1]?.id;
for (const note of newNotes) {
fetchedNoteIds.add(note.id);
}
} else {
nextMaxId = undefined;
}
};
const loadPrev = async () => {
const response = await client.getLocalTimeline({
...ref(options).value,
min_id: prevMinId,
limit: useConfig().NOTES_PER_PAGE,
});
const newNotes = response.data.filter(
(note) => !fetchedNoteIds.has(note.id),
);
if (newNotes.length > 0) {
fetchedNotes.value = [...newNotes, ...fetchedNotes.value];
prevMinId = newNotes[0]?.id;
for (const note of newNotes) {
fetchedNoteIds.add(note.id);
}
} else {
prevMinId = undefined;
}
};
watch(
() => ref(options).value,
async ({ max_id, min_id }) => {
nextMaxId = max_id;
prevMinId = min_id;
await loadNext();
},
{ immediate: true },
);
return { timeline: fetchedNotes, loadNext, loadPrev };
};

View file

@ -12,12 +12,13 @@ export const useNoteContext = (
const output = ref(null as Context | null);
watchEffect(() => {
if (toValue(noteId))
if (toValue(noteId)) {
ref(client)
.value?.getStatusContext(toValue(noteId) ?? "")
.then((res) => {
output.value = res.data;
});
}
});
return output;

View file

@ -21,8 +21,7 @@ export const useNoteData = (
const shouldHide = computed(
() =>
(renderedNote.value?.sensitive ||
!!renderedNote.value?.spoiler_text ||
false) &&
!!renderedNote.value?.spoiler_text) &&
(showContentWarning.value.value as boolean),
);
const mentions = useResolveMentions(

View file

@ -89,13 +89,13 @@ export const useParsedAccount = (
account: MaybeRef<Account | undefined | null>,
settings: MaybeRef<Settings>,
) => {
const display_name = computed(() => toValue(account)?.display_name ?? "");
const displayName = computed(() => toValue(account)?.display_name ?? "");
const note = computed(() => toValue(account)?.note ?? "");
const fields = computed(() => toValue(account)?.fields ?? []);
const emojis = computed(() => toValue(account)?.emojis ?? []);
const parsedDisplayName = useParsedContent(
display_name,
displayName,
emojis,
undefined,
settings,

View file

@ -14,12 +14,13 @@ export const useRelationship = (
}
watchEffect(() => {
if (toValue(accountId))
if (toValue(accountId)) {
toValue(client)
?.getRelationship(toValue(accountId) ?? "")
.then((res) => {
relationship.value = res.data;
});
}
});
watch(relationship, (newOutput, oldOutput) => {

View file

@ -24,11 +24,15 @@ export const useTimeline = <
loadNext: () => Promise<void>;
loadPrev: () => Promise<void>;
} => {
if (!client || !fetchTimeline) {
if (!(client && fetchTimeline)) {
return {
timeline: ref([]),
loadNext: async () => {},
loadPrev: async () => {},
loadNext: async () => {
// ...
},
loadPrev: async () => {
// ...
},
};
}
@ -107,11 +111,15 @@ export const useIdTimeline = <
loadNext: () => Promise<void>;
loadPrev: () => Promise<void>;
} => {
if (!client || !fetchTimeline) {
if (!(client && fetchTimeline)) {
return {
timeline: ref([]),
loadNext: async () => {},
loadPrev: async () => {},
loadNext: async () => {
// ...
},
loadPrev: async () => {
// ...
},
};
}

View file

@ -30,8 +30,12 @@ const loaded = computed(() => note.value !== null && context.value !== null);
watch(
[() => context.value?.ancestors, loaded],
async () => {
if (context.value?.ancestors.length === 0) return;
if (!loaded.value) return;
if (context.value?.ancestors.length === 0) {
return;
}
if (!loaded.value) {
return;
}
await nextTick();
// Wait for 200ms
await new Promise((resolve) => setTimeout(resolve, 200));

View file

@ -111,14 +111,14 @@ const hostname = useRequestURL().hostname;
const query = new URLSearchParams(
window?.location.search ?? useRequestURL().search,
);
const redirect_uri = query.get("redirect_uri");
const response_type = query.get("response_type");
const client_id = query.get("client_id");
const redirectUri = query.get("redirect_uri");
const responseType = query.get("response_type");
const clientId = query.get("client_id");
const scope = query.get("scope");
const error = query.get("error");
const error_description = query.get("error_description");
const errorDescription = query.get("error_description");
const validUrlParameters = redirect_uri && response_type && client_id && scope;
const validUrlParameters = redirectUri && responseType && clientId && scope;
const ssoConfig = useSSOConfig();
</script>

View file

@ -92,11 +92,11 @@ const application = query.application;
const website = query.website
? decodeURIComponent(query.website as string)
: null;
const redirect_uri = query.redirect_uri as string;
const client_id = query.client_id;
const redirectUri = query.redirect_uri as string;
const clientId = query.client_id;
const scope = query.scope ? decodeURIComponent(query.scope as string) : "";
const validUrlParameters = application && redirect_uri && client_id && scope;
const validUrlParameters = application && redirectUri && clientId && scope;
const oauthScopeText: Record<string, string> = {
"rw:accounts": "$VERB your account information",
@ -123,7 +123,7 @@ const scopes = scope.split(" ");
// Return an array of strings to display
// "read write:accounts" returns all the fields with $VERB as read, plus the accounts field with $VERB as write
const getScopeText = (fullScopes: string[]) => {
const scopeTexts = [];
const scopeTexts: string[][] = [];
const readScopes = fullScopes.filter((scope) => scope.includes("read"));
const writeScopes = fullScopes.filter((scope) => scope.includes("write"));
@ -138,12 +138,14 @@ const getScopeText = (fullScopes: string[]) => {
(writeScopes.includes(`write:${scopeName}`) ||
writeScopes.find((scope) => scope === "write"))
) {
if (oauthScopeText[possibleScope]?.includes("$VERB"))
if (oauthScopeText[possibleScope]?.includes("$VERB")) {
scopeTexts.push([
"Read and write",
oauthScopeText[possibleScope]?.replace("$VERB", ""),
oauthScopeText[possibleScope]?.replace("$VERB", "") ?? "",
]);
else scopeTexts.push(["", oauthScopeText[possibleScope]]);
} else {
scopeTexts.push(["", oauthScopeText[possibleScope] ?? ""]);
}
continue;
}
@ -152,12 +154,14 @@ const getScopeText = (fullScopes: string[]) => {
(readScopes.includes(`read:${scopeName}`) ||
readScopes.find((scope) => scope === "read"))
) {
if (oauthScopeText[possibleScope]?.includes("$VERB"))
if (oauthScopeText[possibleScope]?.includes("$VERB")) {
scopeTexts.push([
"Read",
oauthScopeText[possibleScope]?.replace("$VERB", ""),
oauthScopeText[possibleScope]?.replace("$VERB", "") ?? "",
]);
else scopeTexts.push(["", oauthScopeText[possibleScope]]);
} else {
scopeTexts.push(["", oauthScopeText[possibleScope] ?? ""]);
}
}
if (
@ -165,12 +169,14 @@ const getScopeText = (fullScopes: string[]) => {
(writeScopes.includes(`write:${scopeName}`) ||
writeScopes.find((scope) => scope === "write"))
) {
if (oauthScopeText[possibleScope]?.includes("$VERB"))
if (oauthScopeText[possibleScope]?.includes("$VERB")) {
scopeTexts.push([
"Write",
oauthScopeText[possibleScope]?.replace("$VERB", ""),
oauthScopeText[possibleScope]?.replace("$VERB", "") ?? "",
]);
else scopeTexts.push(["", oauthScopeText[possibleScope]]);
} else {
scopeTexts.push(["", oauthScopeText[possibleScope] ?? ""]);
}
}
}
return scopeTexts;

View file

@ -99,14 +99,14 @@ const query = new URLSearchParams(
window?.location.search ?? useRequestURL().search,
);
const token = query.get("token");
const login_reset = query.get("login_reset") === "true";
const loginReset = query.get("login_reset") === "true";
const success = query.get("success") === "true";
let error = query.get("error");
let error_description = query.get("error_description");
let errorDescription = query.get("error_description");
if (login_reset) {
if (loginReset) {
error = "Login reset";
error_description =
errorDescription =
"Your password has been reset by an administrator. Please change it here.";
}

View file

@ -158,10 +158,10 @@ const register = (result: {
"en",
result.reason || "Empty reason",
)
.then(async () => {
.then(() => {
navigateTo("/register/success");
})
.catch(async (e) => {
.catch((e) => {
const error = e as ResponseError<{
error: string;
}>;

View file

@ -59,7 +59,7 @@ export const parseFromJson = (json: Record<string, unknown>) => {
};
export enum SettingIds {
MFM = "mfm",
Mfm = "mfm",
CustomCSS = "custom-css",
Theme = "theme",
CustomEmojis = "custom-emojis",
@ -73,7 +73,7 @@ export enum SettingIds {
export const settings = [
{
id: SettingIds.MFM,
id: SettingIds.Mfm,
title: "Render MFM",
description: "Render Misskey-Flavoured Markdown",
type: SettingType.Boolean,

View file

@ -26,7 +26,7 @@ export const signInWithCode = (code: string, appData: ApplicationData) => {
!identities.value.find(
(i) => i.account.id === accountOutput.data.id,
)
)
) {
identity.value = {
id: nanoid(),
tokens: res.data,
@ -35,6 +35,7 @@ export const signInWithCode = (code: string, appData: ApplicationData) => {
permissions: [],
emojis: [],
};
}
// Remove code from URL
window.history.replaceState(