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 { showSuspendedDialog } from '@/scripts/show-suspended-dialog';
import { i18n } from '@/i18n'; import { i18n } from '@/i18n';
import { del, get, set } from '@/scripts/idb-proxy'; import { del, get, set } from '@/scripts/idb-proxy';
import { apiUrl } from '@/config';
import { waiting, api, popup, popupMenu, success, alert } from '@/os'; import { waiting, api, popup, popupMenu, success, alert } from '@/os';
import { unisonReload, reloadChannel } from '@/scripts/unison-reload'; import { unisonReload, reloadChannel } from '@/scripts/unison-reload';
import { MenuItem } from '@/types/menu';
// TODO: 他のタブと永続化されたstateを同期 // TODO: 他のタブと永続化されたstateを同期
@ -22,7 +22,7 @@ export async function signout() {
waiting(); waiting();
localStorage.removeItem('account'); localStorage.removeItem('account');
await removeAccount($i.id); if ($i) await removeAccount($i!.id);
const accounts = await getAccounts(); const accounts = await getAccounts();
@ -99,14 +99,18 @@ function fetchAccount(token: string): Promise<Account> {
} }
export function updateAccount(accountData) { export function updateAccount(accountData) {
if (!$i) return;
for (const [key, value] of Object.entries(accountData)) { 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() { 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) { export async function login(token: Account['token'], redirect?: string) {
@ -134,39 +138,19 @@ export async function openAccountMenu(opts: {
active?: foundkey.entities.UserDetailed['id']; active?: foundkey.entities.UserDetailed['id'];
onChoose?: (account: foundkey.entities.UserDetailed) => void; onChoose?: (account: foundkey.entities.UserDetailed) => void;
}, ev: MouseEvent) { }, ev: MouseEvent) {
function showSigninDialog() { const storedAccounts = await getAccounts().then(accounts => accounts.filter(x => x.id !== $i?.id));
popup(defineAsyncComponent(() => import('@/components/signin-dialog.vue')), {}, {
done: res => {
addAccount(res.id, res.i);
success();
},
}, 'closed');
}
function createAccount() {
popup(defineAsyncComponent(() => import('@/components/signup-dialog.vue')), {}, {
done: res => {
addAccount(res.id, res.i);
switchAccountWithToken(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) }); const accountsPromise = api('users/show', { userIds: storedAccounts.map(x => x.id) });
function createItem(account: foundkey.entities.UserDetailed) { const switchAccount = async (account: foundkey.entities.UserDetailed) => {
return { 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', type: 'user',
user: account, user: account,
active: opts.active != null ? opts.active === account.id : false, active: opts.active != null ? opts.active === account.id : false,
@ -177,10 +161,8 @@ export async function openAccountMenu(opts: {
switchAccount(account); switchAccount(account);
} }
}, },
}; });
} const accountItemPromises: Promise<MenuItem[]> = storedAccounts.map(a => new Promise(res => {
const accountItemPromises = storedAccounts.map(a => new Promise(res => {
accountsPromise.then(accounts => { accountsPromise.then(accounts => {
const account = accounts.find(x => x.id === a.id); const account = accounts.find(x => x.id === a.id);
if (account == null) return res(null); if (account == null) return res(null);
@ -188,22 +170,40 @@ export async function openAccountMenu(opts: {
}); });
})); }));
const showSigninDialog = () => {
popup(defineAsyncComponent(() => import('@/components/signin-dialog.vue')), {}, {
done: res => {
addAccount(res.id, res.i);
success();
},
}, 'closed');
}
const createAccount = () => {
popup(defineAsyncComponent(() => import('@/components/signup-dialog.vue')), {}, {
done: res => {
addAccount(res.id, res.i);
login(res.i);
},
}, 'closed');
};
if (opts.withExtraOperation) { if (opts.withExtraOperation) {
popupMenu([...[{ popupMenu([...[{
type: 'link', type: 'link',
text: i18n.ts.profile, text: i18n.ts.profile,
to: `/@${ $i.username }`, to: `/@${ $i.username }`,
avatar: $i, avatar: $i,
}, null, ...(opts.includeCurrentAccount ? [createItem($i)] : []), ...accountItemPromises, { }, null, ...(opts.includeCurrentAccount && $i ? [createItem($i)] : []), ...accountItemPromises, {
icon: 'fas fa-plus', icon: 'fas fa-plus',
text: i18n.ts.addAccount, text: i18n.ts.addAccount,
action: () => { action: () => {
popupMenu([{ popupMenu([{
text: i18n.ts.existingAccount, text: i18n.ts.existingAccount,
action: () => { showSigninDialog(); }, action: showSigninDialog,
}, { }, {
text: i18n.ts.createAccount, text: i18n.ts.createAccount,
action: () => { createAccount(); }, action: createAccount,
}], ev.currentTarget ?? ev.target); }], ev.currentTarget ?? ev.target);
}, },
}, { }, {
@ -211,11 +211,11 @@ export async function openAccountMenu(opts: {
icon: 'fas fa-users', icon: 'fas fa-users',
text: i18n.ts.manageAccounts, text: i18n.ts.manageAccounts,
to: '/settings/accounts', to: '/settings/accounts',
}]], ev.currentTarget ?? ev.target, { }]], ev.currentTarget ?? ev.target ?? undefined, {
align: 'left', align: 'left',
}); });
} else { } 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', 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 ast = (this.plain ? mfm.parsePlain : mfm.parse)(this.text, { fnNameList: MFM_TAGS });
const validTime = (t: string | null | undefined) => { const validTime = (t: string | true) => {
if (t == null) return null; if (typeof t !== 'string') return null;
return t.match(/^[0-9.]+s$/) ? t : 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) { switch (token.type) {
case 'text': { case 'text': {
const text = token.props.text.replace(/(\r\n|\n|\r)/g, '\n'); const text = token.props.text.replace(/(\r\n|\n|\r)/g, '\n');
if (!this.plain) { if (!this.plain) {
const res = []; const res: VNode[] = [];
for (const t of text.split('\n')) { for (const t of text.split('\n')) {
res.push(h('br')); res.push(h('br'));
res.push(t); res.push(t);
@ -63,16 +64,16 @@ export default defineComponent({
res.shift(); res.shift();
return res; return res;
} else { } else {
return [text.replace(/\n/g, ' ')]; return text.replace(/\n/g, ' ');
} }
} }
case 'bold': { case 'bold': {
return [h('b', genEl(token.children))]; return h('b', genEl(token.children));
} }
case 'strike': { case 'strike': {
return [h('del', genEl(token.children))]; return h('del', genEl(token.children));
} }
case 'italic': { case 'italic': {
@ -180,7 +181,7 @@ export default defineComponent({
return h(MkSparkle, {}, genEl(token.children)); return h(MkSparkle, {}, genEl(token.children));
} }
case 'rotate': { 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;`; style = `transform: rotate(${degrees}deg); transform-origin: center center;`;
break; break;
} }
@ -195,116 +196,110 @@ export default defineComponent({
} }
case 'small': { case 'small': {
return [h('small', { return h('small', {
style: 'opacity: 0.7;', style: 'opacity: 0.7;',
}, genEl(token.children))]; }, genEl(token.children));
} }
case 'center': { case 'center': {
return [h('div', { return h('div', {
style: 'text-align:center;', style: 'text-align:center;',
}, genEl(token.children))]; }, genEl(token.children));
} }
case 'url': { case 'url': {
return [h(MkUrl, { return h(MkUrl, {
key: Math.random(), key: Math.random(),
url: token.props.url, url: token.props.url,
rel: 'nofollow noopener', rel: 'nofollow noopener',
})]; });
} }
case 'link': { case 'link': {
return [h(MkLink, { return h(MkLink, {
key: Math.random(), key: Math.random(),
url: token.props.url, url: token.props.url,
rel: 'nofollow noopener', rel: 'nofollow noopener',
}, genEl(token.children))]; }, genEl(token.children));
} }
case 'mention': { case 'mention': {
return [h(MkMention, { return h(MkMention, {
key: Math.random(), key: Math.random(),
host: (token.props.host == null && this.author && this.author.host != null ? this.author.host : token.props.host) || host, host: (token.props.host == null && this.author && this.author.host != null ? this.author.host : token.props.host) || host,
username: token.props.username, username: token.props.username,
})]; });
} }
case 'hashtag': { case 'hashtag': {
return [h(MkA, { return h(MkA, {
key: Math.random(), key: Math.random(),
to: this.isNote ? `/tags/${encodeURIComponent(token.props.hashtag)}` : `/explore/tags/${encodeURIComponent(token.props.hashtag)}`, to: this.isNote ? `/tags/${encodeURIComponent(token.props.hashtag)}` : `/explore/tags/${encodeURIComponent(token.props.hashtag)}`,
style: 'color:var(--hashtag);', style: 'color:var(--hashtag);',
}, `#${token.props.hashtag}`)]; }, `#${token.props.hashtag}`);
} }
case 'blockCode': { case 'blockCode': {
return [h(MkCode, { return h(MkCode, {
key: Math.random(), key: Math.random(),
code: token.props.code, code: token.props.code,
lang: token.props.lang, lang: token.props.lang,
})]; });
} }
case 'inlineCode': { case 'inlineCode': {
return [h(MkCode, { return h(MkCode, {
key: Math.random(), key: Math.random(),
code: token.props.code, code: token.props.code,
inline: true, inline: true,
})]; });
} }
case 'quote': { case 'quote': {
if (!this.nowrap) { return h(this.nowrap ? 'span' : 'div', {
return [h('div', {
class: 'quote', class: 'quote',
}, genEl(token.children))]; }, genEl(token.children));
} else {
return [h('span', {
class: 'quote',
}, genEl(token.children))];
}
} }
case 'emojiCode': { case 'emojiCode': {
return [h(MkEmoji, { return h(MkEmoji, {
key: Math.random(), key: Math.random(),
emoji: `:${token.props.name}:`, emoji: `:${token.props.name}:`,
customEmojis: this.customEmojis, customEmojis: this.customEmojis,
normal: this.plain, normal: this.plain,
})]; });
} }
case 'unicodeEmoji': { case 'unicodeEmoji': {
return [h(MkEmoji, { return h(MkEmoji, {
key: Math.random(), key: Math.random(),
emoji: token.props.emoji, emoji: token.props.emoji,
customEmojis: this.customEmojis, customEmojis: this.customEmojis,
normal: this.plain, normal: this.plain,
})]; });
} }
case 'mathInline': { case 'mathInline': {
return [h(MkFormula, { return h(MkFormula, {
key: Math.random(), key: Math.random(),
formula: token.props.formula, formula: token.props.formula,
block: false, block: false,
})]; });
} }
case 'mathBlock': { case 'mathBlock': {
return [h(MkFormula, { return h(MkFormula, {
key: Math.random(), key: Math.random(),
formula: token.props.formula, formula: token.props.formula,
block: true, block: true,
})]; });
} }
case 'search': { case 'search': {
return [h(MkSearch, { return h(MkSearch, {
key: Math.random(), key: Math.random(),
q: token.props.query, q: token.props.query,
})]; });
} }
default: { default: {

View file

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

View file

@ -10,7 +10,7 @@ class TooltipDirective {
public text: string | null; public text: string | null;
private asMfm: boolean; private asMfm: boolean;
private _close: null | () => void; private _close: null | (() => void);
private showTimer: null | ReturnType<typeof window.setTimeout>; private showTimer: null | ReturnType<typeof window.setTimeout>;
private hideTimer: null | ReturnType<typeof window.setTimeout>; private hideTimer: null | ReturnType<typeof window.setTimeout>;
@ -23,7 +23,7 @@ class TooltipDirective {
this.hideTimer = null; this.hideTimer = null;
} }
private close(): void { public close(): void {
if (this.hideTimer != null) return; // already closed or closing if (this.hideTimer != null) return; // already closed or closing
// cancel any pending attempts to show // cancel any pending attempts to show
@ -96,7 +96,7 @@ export default {
const end = isTouchUsing ? 'touchend' : 'mouseleave'; const end = isTouchUsing ? 'touchend' : 'mouseleave';
el.addEventListener(start, () => self.show(el), { passive: true }); el.addEventListener(start, () => self.show(el), { passive: true });
el.addEventListener(end, () => self.close(), { 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()); 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 authorizationToken = token ?? $i?.token ?? undefined;
const authorization = authorizationToken ? `Bearer ${authorizationToken}` : 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}`, { fetch(endpoint.indexOf('://') > -1 ? endpoint : `${apiUrl}/${endpoint}`, {
method: 'POST', method: 'POST',
body: JSON.stringify(data), 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 authorizationToken = token ?? $i?.token ?? undefined;
const authorization = authorizationToken ? `Bearer ${authorizationToken}` : undefined; const authorization = authorizationToken ? `Bearer ${authorizationToken}` : undefined;
const promise = new Promise((resolve, reject) => { const promise = new Promise<void>((resolve, reject) => {
// Send request // Send request
fetch(`${apiUrl}/${endpoint}?${query}`, { fetch(`${apiUrl}/${endpoint}?${query}`, {
method: 'GET', method: 'GET',
@ -103,7 +103,7 @@ export const apiWithDialog = ((
promiseDialog(promise, null, (err) => { promiseDialog(promise, null, (err) => {
alert({ alert({
type: 'error', 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; text?: string | null;
placeholder?: string | null; placeholder?: string | null;
default?: Date | null; default?: Date | null;
}): Promise<{ canceled: true; result: undefined; } | { }): Promise<{ canceled: true; } | { canceled: false; result: Date; }> {
canceled: false; result: Date;
}> {
return new Promise((resolve) => { return new Promise((resolve) => {
popup(defineAsyncComponent(() => import('@/components/dialog.vue')), { popup(defineAsyncComponent(() => import('@/components/dialog.vue')), {
title: props.title, title: props.title,
@ -351,7 +349,7 @@ export function select<C = any>(props: {
} }
export function success() { export function success() {
return new Promise((resolve) => { return new Promise<void>((resolve) => {
const showing = ref(true); const showing = ref(true);
window.setTimeout(() => { window.setTimeout(() => {
showing.value = false; showing.value = false;
@ -366,7 +364,7 @@ export function success() {
} }
export function waiting() { export function waiting() {
return new Promise((resolve) => { return new Promise<void>((resolve) => {
const showing = ref(true); const showing = ref(true);
popup(defineAsyncComponent(() => import('@/components/waiting-dialog.vue')), { popup(defineAsyncComponent(() => import('@/components/waiting-dialog.vue')), {
success: false, success: false,
@ -571,17 +569,3 @@ export function post(props: Record<string, any> = {}) {
} }
export const deckGlobalEvents = new EventEmitter(); 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 { ColdDeviceStorage, defaultStore } from '@/store';
import { addTheme } from '@/theme-store'; import { addTheme } from '@/theme-store';
import { i18n } from '@/i18n'; import { i18n } from '@/i18n';
import { useLeaveGuard } from '@/scripts/use-leave-guard';
import { definePageMetadata } from '@/scripts/page-metadata'; import { definePageMetadata } from '@/scripts/page-metadata';
const bgColors = [ const bgColors = [
@ -125,9 +124,6 @@ let theme = $ref<Partial<Theme>>({
}); });
let description = $ref<string | null>(null); let description = $ref<string | null>(null);
let themeCode = $ref<string | null>(null); let themeCode = $ref<string | null>(null);
let changed = $ref(false);
useLeaveGuard($$(changed));
function showPreview() { function showPreview() {
os.pageWindow('/preview'); os.pageWindow('/preview');
@ -162,7 +158,6 @@ function setFgColor(color) {
function apply() { function apply() {
themeCode = JSON5.stringify(theme, null, '\t'); themeCode = JSON5.stringify(theme, null, '\t');
applyTheme(theme, false); applyTheme(theme, false);
changed = true;
} }
function applyThemeCode() { function applyThemeCode() {
@ -199,7 +194,6 @@ async function saveAs() {
} else { } else {
ColdDeviceStorage.set('lightTheme', theme); ColdDeviceStorage.set('lightTheme', theme);
} }
changed = false;
os.alert({ os.alert({
type: 'success', type: 'success',
text: i18n.t('_theme.installed', { name: theme.name }), 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 { markRaw, ref } from 'vue';
import { Storage } from '@/pizzax'; import { Storage } from '@/pizzax';
import { Theme } from '@/scripts/theme';
export const postFormActions = []; export const postFormActions = [];
export const userActions = []; export const userActions = [];

View file

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