fix some lints

This commit is contained in:
Johann150 2023-05-07 17:12:04 +02:00
parent a10b8875d9
commit 7e1ea09458
Signed by untrusted user: Johann150
GPG key ID: 9EE6577A2A06F8F1
9 changed files with 98 additions and 175 deletions

View file

@ -3,9 +3,9 @@ import * as foundkey from 'foundkey-js';
import { showSuspendedDialog } from '@/scripts/show-suspended-dialog';
import { i18n } from '@/i18n';
import { del, get, set } from '@/scripts/idb-proxy';
import { apiUrl } from '@/config';
import { waiting, api, popup, popupMenu, success, alert } from '@/os';
import { unisonReload, reloadChannel } from '@/scripts/unison-reload';
import { MenuItem } from '@/types/menu';
// TODO: 他のタブと永続化されたstateを同期
@ -22,7 +22,7 @@ export async function signout() {
waiting();
localStorage.removeItem('account');
await removeAccount($i.id);
if ($i) await removeAccount($i!.id);
const accounts = await getAccounts();
@ -99,14 +99,18 @@ function fetchAccount(token: string): Promise<Account> {
}
export function updateAccount(accountData) {
if (!$i) return;
for (const [key, value] of Object.entries(accountData)) {
$i[key] = value;
$i![key] = value;
}
localStorage.setItem('account', JSON.stringify($i));
localStorage.setItem('account', JSON.stringify($i!));
}
export function refreshAccount() {
return fetchAccount($i.token).then(updateAccount);
if (!$i) return;
return fetchAccount($i!.token).then(updateAccount);
}
export async function login(token: Account['token'], redirect?: string) {
@ -134,7 +138,39 @@ export async function openAccountMenu(opts: {
active?: foundkey.entities.UserDetailed['id'];
onChoose?: (account: foundkey.entities.UserDetailed) => void;
}, ev: MouseEvent) {
function showSigninDialog() {
const storedAccounts = await getAccounts().then(accounts => accounts.filter(x => x.id !== $i?.id));
const accountsPromise = api('users/show', { userIds: storedAccounts.map(x => x.id) });
const switchAccount = async (account: foundkey.entities.UserDetailed) => {
const storedAccounts = await getAccounts();
const token = storedAccounts.find(x => x.id === account.id)?.token;
if (!token) {
// TODO error handling?
} else {
login(token);
}
};
const createItem = (account: foundkey.entities.UserDetailed): MenuItem => ({
type: 'user',
user: account,
active: opts.active != null ? opts.active === account.id : false,
action: () => {
if (opts.onChoose) {
opts.onChoose(account);
} else {
switchAccount(account);
}
},
});
const accountItemPromises: Promise<MenuItem[]> = storedAccounts.map(a => new Promise(res => {
accountsPromise.then(accounts => {
const account = accounts.find(x => x.id === a.id);
if (account == null) return res(null);
res(createItem(account));
});
}));
const showSigninDialog = () => {
popup(defineAsyncComponent(() => import('@/components/signin-dialog.vue')), {}, {
done: res => {
addAccount(res.id, res.i);
@ -143,50 +179,14 @@ export async function openAccountMenu(opts: {
}, 'closed');
}
function createAccount() {
const createAccount = () => {
popup(defineAsyncComponent(() => import('@/components/signup-dialog.vue')), {}, {
done: res => {
addAccount(res.id, res.i);
switchAccountWithToken(res.i);
login(res.i);
},
}, 'closed');
}
async function switchAccount(account: foundkey.entities.UserDetailed) {
const storedAccounts = await getAccounts();
const token = storedAccounts.find(x => x.id === account.id).token;
switchAccountWithToken(token);
}
function switchAccountWithToken(token: string) {
login(token);
}
const storedAccounts = await getAccounts().then(accounts => accounts.filter(x => x.id !== $i.id));
const accountsPromise = api('users/show', { userIds: storedAccounts.map(x => x.id) });
function createItem(account: foundkey.entities.UserDetailed) {
return {
type: 'user',
user: account,
active: opts.active != null ? opts.active === account.id : false,
action: () => {
if (opts.onChoose) {
opts.onChoose(account);
} else {
switchAccount(account);
}
},
};
}
const accountItemPromises = storedAccounts.map(a => new Promise(res => {
accountsPromise.then(accounts => {
const account = accounts.find(x => x.id === a.id);
if (account == null) return res(null);
res(createItem(account));
});
}));
};
if (opts.withExtraOperation) {
popupMenu([...[{
@ -194,16 +194,16 @@ export async function openAccountMenu(opts: {
text: i18n.ts.profile,
to: `/@${ $i.username }`,
avatar: $i,
}, null, ...(opts.includeCurrentAccount ? [createItem($i)] : []), ...accountItemPromises, {
}, null, ...(opts.includeCurrentAccount && $i ? [createItem($i)] : []), ...accountItemPromises, {
icon: 'fas fa-plus',
text: i18n.ts.addAccount,
action: () => {
popupMenu([{
text: i18n.ts.existingAccount,
action: () => { showSigninDialog(); },
action: showSigninDialog,
}, {
text: i18n.ts.createAccount,
action: () => { createAccount(); },
action: createAccount,
}], ev.currentTarget ?? ev.target);
},
}, {
@ -211,11 +211,11 @@ export async function openAccountMenu(opts: {
icon: 'fas fa-users',
text: i18n.ts.manageAccounts,
to: '/settings/accounts',
}]], ev.currentTarget ?? ev.target, {
}]], ev.currentTarget ?? ev.target ?? undefined, {
align: 'left',
});
} else {
popupMenu([...(opts.includeCurrentAccount ? [createItem($i)] : []), ...accountItemPromises], ev.currentTarget ?? ev.target, {
popupMenu([...(opts.includeCurrentAccount && $i ? [createItem($i)] : []), ...accountItemPromises], ev.currentTarget ?? ev.target ?? undefined, {
align: 'left',
});
}

View file

@ -44,18 +44,19 @@ export default defineComponent({
const ast = (this.plain ? mfm.parsePlain : mfm.parse)(this.text, { fnNameList: MFM_TAGS });
const validTime = (t: string | null | undefined) => {
if (t == null) return null;
const validTime = (t: string | true) => {
if (typeof t !== 'string') return null;
return t.match(/^[0-9.]+s$/) ? t : null;
};
const genEl = (ast: mfm.MfmNode[]) => ast.map((token): VNode[] => {
const genEl = (ast: mfm.MfmNode[]) => ast.map((token): VNode | VNode[] => {
switch (token.type) {
case 'text': {
const text = token.props.text.replace(/(\r\n|\n|\r)/g, '\n');
if (!this.plain) {
const res = [];
const res: VNode[] = [];
for (const t of text.split('\n')) {
res.push(h('br'));
res.push(t);
@ -63,16 +64,16 @@ export default defineComponent({
res.shift();
return res;
} else {
return [text.replace(/\n/g, ' ')];
return text.replace(/\n/g, ' ');
}
}
case 'bold': {
return [h('b', genEl(token.children))];
return h('b', genEl(token.children));
}
case 'strike': {
return [h('del', genEl(token.children))];
return h('del', genEl(token.children));
}
case 'italic': {
@ -180,7 +181,7 @@ export default defineComponent({
return h(MkSparkle, {}, genEl(token.children));
}
case 'rotate': {
const degrees = parseInt(token.props.args.deg) || '90';
const degrees = (typeof token.props.args.deg === 'string' ? parseInt(token.props.args.deg) : null) || '90';
style = `transform: rotate(${degrees}deg); transform-origin: center center;`;
break;
}
@ -195,116 +196,110 @@ export default defineComponent({
}
case 'small': {
return [h('small', {
return h('small', {
style: 'opacity: 0.7;',
}, genEl(token.children))];
}, genEl(token.children));
}
case 'center': {
return [h('div', {
return h('div', {
style: 'text-align:center;',
}, genEl(token.children))];
}, genEl(token.children));
}
case 'url': {
return [h(MkUrl, {
return h(MkUrl, {
key: Math.random(),
url: token.props.url,
rel: 'nofollow noopener',
})];
});
}
case 'link': {
return [h(MkLink, {
return h(MkLink, {
key: Math.random(),
url: token.props.url,
rel: 'nofollow noopener',
}, genEl(token.children))];
}, genEl(token.children));
}
case 'mention': {
return [h(MkMention, {
return h(MkMention, {
key: Math.random(),
host: (token.props.host == null && this.author && this.author.host != null ? this.author.host : token.props.host) || host,
username: token.props.username,
})];
});
}
case 'hashtag': {
return [h(MkA, {
return h(MkA, {
key: Math.random(),
to: this.isNote ? `/tags/${encodeURIComponent(token.props.hashtag)}` : `/explore/tags/${encodeURIComponent(token.props.hashtag)}`,
style: 'color:var(--hashtag);',
}, `#${token.props.hashtag}`)];
}, `#${token.props.hashtag}`);
}
case 'blockCode': {
return [h(MkCode, {
return h(MkCode, {
key: Math.random(),
code: token.props.code,
lang: token.props.lang,
})];
});
}
case 'inlineCode': {
return [h(MkCode, {
return h(MkCode, {
key: Math.random(),
code: token.props.code,
inline: true,
})];
});
}
case 'quote': {
if (!this.nowrap) {
return [h('div', {
class: 'quote',
}, genEl(token.children))];
} else {
return [h('span', {
class: 'quote',
}, genEl(token.children))];
}
return h(this.nowrap ? 'span' : 'div', {
class: 'quote',
}, genEl(token.children));
}
case 'emojiCode': {
return [h(MkEmoji, {
return h(MkEmoji, {
key: Math.random(),
emoji: `:${token.props.name}:`,
customEmojis: this.customEmojis,
normal: this.plain,
})];
});
}
case 'unicodeEmoji': {
return [h(MkEmoji, {
return h(MkEmoji, {
key: Math.random(),
emoji: token.props.emoji,
customEmojis: this.customEmojis,
normal: this.plain,
})];
});
}
case 'mathInline': {
return [h(MkFormula, {
return h(MkFormula, {
key: Math.random(),
formula: token.props.formula,
block: false,
})];
});
}
case 'mathBlock': {
return [h(MkFormula, {
return h(MkFormula, {
key: Math.random(),
formula: token.props.formula,
block: true,
})];
});
}
case 'search': {
return [h(MkSearch, {
return h(MkSearch, {
key: Math.random(),
q: token.props.query,
})];
});
}
default: {

View file

@ -43,7 +43,7 @@ export default {
calc(src);
},
unmounted(src) {
unmounted(src, binding) {
binding.value(0, 0);
const info = mountings.get(src);
if (!info) return;

View file

@ -10,7 +10,7 @@ class TooltipDirective {
public text: string | null;
private asMfm: boolean;
private _close: null | () => void;
private _close: null | (() => void);
private showTimer: null | ReturnType<typeof window.setTimeout>;
private hideTimer: null | ReturnType<typeof window.setTimeout>;
@ -23,7 +23,7 @@ class TooltipDirective {
this.hideTimer = null;
}
private close(): void {
public close(): void {
if (this.hideTimer != null) return; // already closed or closing
// cancel any pending attempts to show
@ -96,7 +96,7 @@ export default {
const end = isTouchUsing ? 'touchend' : 'mouseleave';
el.addEventListener(start, () => self.show(el), { passive: true });
el.addEventListener(end, () => self.close(), { passive: true });
el.addEventListener('click', self.close());
el.addEventListener('click', () => self.close());
el.addEventListener('selectstart', ev => ev.preventDefault());
},

View file

@ -26,7 +26,7 @@ export const api = ((endpoint: string, data: Record<string, any> = {}, token?: s
const authorizationToken = token ?? $i?.token ?? undefined;
const authorization = authorizationToken ? `Bearer ${authorizationToken}` : undefined;
const promise = new Promise((resolve, reject) => {
const promise = new Promise<void>((resolve, reject) => {
fetch(endpoint.indexOf('://') > -1 ? endpoint : `${apiUrl}/${endpoint}`, {
method: 'POST',
body: JSON.stringify(data),
@ -66,7 +66,7 @@ export const apiGet = ((endpoint: string, data: Record<string, any> = {}, token?
const authorizationToken = token ?? $i?.token ?? undefined;
const authorization = authorizationToken ? `Bearer ${authorizationToken}` : undefined;
const promise = new Promise((resolve, reject) => {
const promise = new Promise<void>((resolve, reject) => {
// Send request
fetch(`${apiUrl}/${endpoint}?${query}`, {
method: 'GET',
@ -103,7 +103,7 @@ export const apiWithDialog = ((
promiseDialog(promise, null, (err) => {
alert({
type: 'error',
text: (err.message + '\n' + (err?.endpoint ?? '') + ' ' + (err?.code ?? '')).trim(),
text: (err.message + '\n' + (err.endpoint ?? '') + ' ' + (err.code ?? '')).trim(),
});
});
@ -293,9 +293,7 @@ export function inputDate(props: {
text?: string | null;
placeholder?: string | null;
default?: Date | null;
}): Promise<{ canceled: true; result: undefined; } | {
canceled: false; result: Date;
}> {
}): Promise<{ canceled: true; } | { canceled: false; result: Date; }> {
return new Promise((resolve) => {
popup(defineAsyncComponent(() => import('@/components/dialog.vue')), {
title: props.title,
@ -351,7 +349,7 @@ export function select<C = any>(props: {
}
export function success() {
return new Promise((resolve) => {
return new Promise<void>((resolve) => {
const showing = ref(true);
window.setTimeout(() => {
showing.value = false;
@ -366,7 +364,7 @@ export function success() {
}
export function waiting() {
return new Promise((resolve) => {
return new Promise<void>((resolve) => {
const showing = ref(true);
popup(defineAsyncComponent(() => import('@/components/waiting-dialog.vue')), {
success: false,
@ -571,17 +569,3 @@ export function post(props: Record<string, any> = {}) {
}
export const deckGlobalEvents = new EventEmitter();
/*
export function checkExistence(fileData: ArrayBuffer): Promise<any> {
return new Promise((resolve) => {
const data = new FormData();
data.append('md5', getMD5(fileData));
os.api('drive/files/find-by-hash', {
md5: getMD5(fileData)
}).then(resp => {
resolve(resp.length > 0 ? resp[0] : null);
});
});
}*/

View file

@ -87,7 +87,6 @@ import * as os from '@/os';
import { ColdDeviceStorage, defaultStore } from '@/store';
import { addTheme } from '@/theme-store';
import { i18n } from '@/i18n';
import { useLeaveGuard } from '@/scripts/use-leave-guard';
import { definePageMetadata } from '@/scripts/page-metadata';
const bgColors = [
@ -125,9 +124,6 @@ let theme = $ref<Partial<Theme>>({
});
let description = $ref<string | null>(null);
let themeCode = $ref<string | null>(null);
let changed = $ref(false);
useLeaveGuard($$(changed));
function showPreview() {
os.pageWindow('/preview');
@ -162,7 +158,6 @@ function setFgColor(color) {
function apply() {
themeCode = JSON5.stringify(theme, null, '\t');
applyTheme(theme, false);
changed = true;
}
function applyThemeCode() {
@ -199,7 +194,6 @@ async function saveAs() {
} else {
ColdDeviceStorage.set('lightTheme', theme);
}
changed = false;
os.alert({
type: 'success',
text: i18n.t('_theme.installed', { name: theme.name }),

View file

@ -1,47 +0,0 @@
import { inject, onUnmounted, Ref } from 'vue';
import { i18n } from '@/i18n';
import * as os from '@/os';
export function useLeaveGuard(enabled: Ref<boolean>) {
/* TODO
const setLeaveGuard = inject('setLeaveGuard');
if (setLeaveGuard) {
setLeaveGuard(async () => {
if (!enabled.value) return false;
const { canceled } = await os.confirm({
type: 'warning',
text: i18n.ts.leaveConfirm,
});
return canceled;
});
} else {
onBeforeRouteLeave(async (to, from) => {
if (!enabled.value) return true;
const { canceled } = await os.confirm({
type: 'warning',
text: i18n.ts.leaveConfirm,
});
return !canceled;
});
}
*/
/*
function onBeforeLeave(ev: BeforeUnloadEvent) {
if (enabled.value) {
ev.preventDefault();
ev.returnValue = '';
}
}
window.addEventListener('beforeunload', onBeforeLeave);
onUnmounted(() => {
window.removeEventListener('beforeunload', onBeforeLeave);
});
*/
}

View file

@ -1,6 +1,5 @@
import { markRaw, ref } from 'vue';
import { Storage } from '@/pizzax';
import { Theme } from '@/scripts/theme';
export const postFormActions = [];
export const userActions = [];

View file

@ -1,7 +1,5 @@
import { inject } from 'vue';
import { post } from '@/os';
import { $i, login } from '@/account';
import { defaultStore } from '@/store';
import { getAccountFromId } from '@/scripts/get-account-from-id';
import { mainRouter } from '@/router';