forked from FoundKeyGang/FoundKey
fix some lints
This commit is contained in:
parent
a10b8875d9
commit
7e1ea09458
9 changed files with 98 additions and 175 deletions
|
@ -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',
|
||||
});
|
||||
}
|
||||
|
|
|
@ -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: {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
},
|
||||
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
});
|
||||
}*/
|
||||
|
|
|
@ -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 }),
|
||||
|
|
|
@ -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);
|
||||
});
|
||||
*/
|
||||
}
|
|
@ -1,6 +1,5 @@
|
|||
import { markRaw, ref } from 'vue';
|
||||
import { Storage } from '@/pizzax';
|
||||
import { Theme } from '@/scripts/theme';
|
||||
|
||||
export const postFormActions = [];
|
||||
export const userActions = [];
|
||||
|
|
|
@ -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';
|
||||
|
||||
|
|
Loading…
Reference in a new issue