mirror of
https://activitypub.software/TransFem-org/Sharkey
synced 2024-12-22 08:20:10 +00:00
lint
This commit is contained in:
parent
3bb7afe544
commit
0fb9c372dd
22 changed files with 69 additions and 71 deletions
|
@ -55,6 +55,7 @@ module.exports = {
|
||||||
'vue/multi-word-component-names': 'warn',
|
'vue/multi-word-component-names': 'warn',
|
||||||
'vue/require-v-for-key': 'warn',
|
'vue/require-v-for-key': 'warn',
|
||||||
'vue/no-unused-components': 'warn',
|
'vue/no-unused-components': 'warn',
|
||||||
|
'vue/no-unused-vars': 'warn',
|
||||||
'vue/valid-v-for': 'warn',
|
'vue/valid-v-for': 'warn',
|
||||||
'vue/return-in-computed-property': 'warn',
|
'vue/return-in-computed-property': 'warn',
|
||||||
'vue/no-setup-props-destructure': 'warn',
|
'vue/no-setup-props-destructure': 'warn',
|
||||||
|
|
|
@ -43,7 +43,7 @@ const emit = defineEmits<{
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const uiWindow = shallowRef<InstanceType<typeof MkWindow>>();
|
const uiWindow = shallowRef<InstanceType<typeof MkWindow>>();
|
||||||
const comment = ref(props.initialComment || '');
|
const comment = ref(props.initialComment ?? '');
|
||||||
|
|
||||||
function send() {
|
function send() {
|
||||||
os.apiWithDialog('users/report-abuse', {
|
os.apiWithDialog('users/report-abuse', {
|
||||||
|
|
|
@ -209,7 +209,7 @@ function exec() {
|
||||||
}
|
}
|
||||||
} else if (props.type === 'hashtag') {
|
} else if (props.type === 'hashtag') {
|
||||||
if (!props.q || props.q === '') {
|
if (!props.q || props.q === '') {
|
||||||
hashtags.value = JSON.parse(miLocalStorage.getItem('hashtags') || '[]');
|
hashtags.value = JSON.parse(miLocalStorage.getItem('hashtags') ?? '[]');
|
||||||
fetching.value = false;
|
fetching.value = false;
|
||||||
} else {
|
} else {
|
||||||
const cacheKey = `autocomplete:hashtag:${props.q}`;
|
const cacheKey = `autocomplete:hashtag:${props.q}`;
|
||||||
|
|
|
@ -69,7 +69,7 @@ const captcha = computed<Captcha>(() => window[variable.value] || {} as unknown
|
||||||
if (loaded) {
|
if (loaded) {
|
||||||
available.value = true;
|
available.value = true;
|
||||||
} else {
|
} else {
|
||||||
(document.getElementById(scriptId.value) || document.head.appendChild(Object.assign(document.createElement('script'), {
|
(document.getElementById(scriptId.value) ?? document.head.appendChild(Object.assign(document.createElement('script'), {
|
||||||
async: true,
|
async: true,
|
||||||
id: scriptId.value,
|
id: scriptId.value,
|
||||||
src: src.value,
|
src: src.value,
|
||||||
|
|
|
@ -45,8 +45,8 @@ onMounted(() => {
|
||||||
src: media.url,
|
src: media.url,
|
||||||
w: media.properties.width,
|
w: media.properties.width,
|
||||||
h: media.properties.height,
|
h: media.properties.height,
|
||||||
alt: media.comment || media.name,
|
alt: media.comment ?? media.name,
|
||||||
comment: media.comment || media.name,
|
comment: media.comment ?? media.name,
|
||||||
};
|
};
|
||||||
if (media.properties.orientation != null && media.properties.orientation >= 5) {
|
if (media.properties.orientation != null && media.properties.orientation >= 5) {
|
||||||
[item.w, item.h] = [item.h, item.w];
|
[item.w, item.h] = [item.h, item.w];
|
||||||
|
@ -90,8 +90,8 @@ onMounted(() => {
|
||||||
[itemData.w, itemData.h] = [itemData.h, itemData.w];
|
[itemData.w, itemData.h] = [itemData.h, itemData.w];
|
||||||
}
|
}
|
||||||
itemData.msrc = file.thumbnailUrl;
|
itemData.msrc = file.thumbnailUrl;
|
||||||
itemData.alt = file.comment || file.name;
|
itemData.alt = file.comment ?? file.name;
|
||||||
itemData.comment = file.comment || file.name;
|
itemData.comment = file.comment ?? file.name;
|
||||||
itemData.thumbCropped = true;
|
itemData.thumbCropped = true;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ const props = withDefaults(defineProps<{
|
||||||
showGlobalToggle: true,
|
showGlobalToggle: true,
|
||||||
});
|
});
|
||||||
|
|
||||||
let includingTypes = $computed(() => props.includingTypes || []);
|
let includingTypes = $computed(() => props.includingTypes ?? []);
|
||||||
|
|
||||||
const dialog = $shallowRef<InstanceType<typeof MkModalWindow>>();
|
const dialog = $shallowRef<InstanceType<typeof MkModalWindow>>();
|
||||||
|
|
||||||
|
|
|
@ -104,7 +104,7 @@ const {
|
||||||
enableInfiniteScroll,
|
enableInfiniteScroll,
|
||||||
} = defaultStore.reactiveState;
|
} = defaultStore.reactiveState;
|
||||||
|
|
||||||
const contentEl = $computed(() => props.pagination.pageEl || rootEl);
|
const contentEl = $computed(() => props.pagination.pageEl ?? rootEl);
|
||||||
const scrollableElement = $computed(() => getScrollContainer(contentEl));
|
const scrollableElement = $computed(() => getScrollContainer(contentEl));
|
||||||
|
|
||||||
// 先頭が表示されているかどうかを検出
|
// 先頭が表示されているかどうかを検出
|
||||||
|
|
|
@ -154,7 +154,7 @@ let autocomplete = $ref(null);
|
||||||
let draghover = $ref(false);
|
let draghover = $ref(false);
|
||||||
let quoteId = $ref(null);
|
let quoteId = $ref(null);
|
||||||
let hasNotSpecifiedMentions = $ref(false);
|
let hasNotSpecifiedMentions = $ref(false);
|
||||||
let recentHashtags = $ref(JSON.parse(miLocalStorage.getItem('hashtags') || '[]'));
|
let recentHashtags = $ref(JSON.parse(miLocalStorage.getItem('hashtags') ?? '[]'));
|
||||||
let imeText = $ref('');
|
let imeText = $ref('');
|
||||||
|
|
||||||
const draftKey = $computed((): string => {
|
const draftKey = $computed((): string => {
|
||||||
|
@ -533,7 +533,7 @@ function onDrop(ev): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
function saveDraft() {
|
function saveDraft() {
|
||||||
const draftData = JSON.parse(miLocalStorage.getItem('drafts') || '{}');
|
const draftData = JSON.parse(miLocalStorage.getItem('drafts') ?? '{}');
|
||||||
|
|
||||||
draftData[draftKey] = {
|
draftData[draftKey] = {
|
||||||
updatedAt: new Date(),
|
updatedAt: new Date(),
|
||||||
|
@ -642,7 +642,7 @@ async function post(ev?: MouseEvent) {
|
||||||
emit('posted');
|
emit('posted');
|
||||||
if (postData.text && postData.text !== '') {
|
if (postData.text && postData.text !== '') {
|
||||||
const hashtags_ = mfm.parse(postData.text).filter(x => x.type === 'hashtag').map(x => x.props.hashtag);
|
const hashtags_ = mfm.parse(postData.text).filter(x => x.type === 'hashtag').map(x => x.props.hashtag);
|
||||||
const history = JSON.parse(miLocalStorage.getItem('hashtags') || '[]') as string[];
|
const history = JSON.parse(miLocalStorage.getItem('hashtags') ?? '[]') as string[];
|
||||||
miLocalStorage.setItem('hashtags', JSON.stringify(unique(hashtags_.concat(history))));
|
miLocalStorage.setItem('hashtags', JSON.stringify(unique(hashtags_.concat(history))));
|
||||||
}
|
}
|
||||||
posting = false;
|
posting = false;
|
||||||
|
@ -746,7 +746,7 @@ onMounted(() => {
|
||||||
nextTick(() => {
|
nextTick(() => {
|
||||||
// 書きかけの投稿を復元
|
// 書きかけの投稿を復元
|
||||||
if (!props.instant && !props.mention && !props.specified) {
|
if (!props.instant && !props.mention && !props.specified) {
|
||||||
const draft = JSON.parse(miLocalStorage.getItem('drafts') || '{}')[draftKey];
|
const draft = JSON.parse(miLocalStorage.getItem('drafts') ?? '{}')[draftKey];
|
||||||
if (draft) {
|
if (draft) {
|
||||||
text = draft.data.text;
|
text = draft.data.text;
|
||||||
useCw = draft.data.useCw;
|
useCw = draft.data.useCw;
|
||||||
|
|
|
@ -16,7 +16,7 @@
|
||||||
<template #label>{{ i18n.ts.username }}</template>
|
<template #label>{{ i18n.ts.username }}</template>
|
||||||
<template #prefix>@</template>
|
<template #prefix>@</template>
|
||||||
</MkInput>
|
</MkInput>
|
||||||
<MkInput v-model="host" @update:model-value="search" :datalist="[hostname]">
|
<MkInput v-model="host" :datalist="[hostname]" @update:model-value="search">
|
||||||
<template #label>{{ i18n.ts.host }}</template>
|
<template #label>{{ i18n.ts.host }}</template>
|
||||||
<template #prefix>@</template>
|
<template #prefix>@</template>
|
||||||
</MkInput>
|
</MkInput>
|
||||||
|
|
|
@ -24,7 +24,7 @@ const rawUrl = computed(() => {
|
||||||
return props.url;
|
return props.url;
|
||||||
}
|
}
|
||||||
if (props.host == null && !customEmojiName.value.includes('@')) {
|
if (props.host == null && !customEmojiName.value.includes('@')) {
|
||||||
return customEmojis.value.find(x => x.name === customEmojiName.value)?.url || null;
|
return customEmojis.value.find(x => x.name === customEmojiName.value)?.url ?? null;
|
||||||
}
|
}
|
||||||
return props.host ? `/emoji/${customEmojiName.value}@${props.host}.webp` : `/emoji/${customEmojiName.value}.webp`;
|
return props.host ? `/emoji/${customEmojiName.value}@${props.host}.webp` : `/emoji/${customEmojiName.value}.webp`;
|
||||||
});
|
});
|
||||||
|
@ -32,7 +32,7 @@ const rawUrl = computed(() => {
|
||||||
const url = computed(() =>
|
const url = computed(() =>
|
||||||
defaultStore.reactiveState.disableShowingAnimatedImages.value && rawUrl.value
|
defaultStore.reactiveState.disableShowingAnimatedImages.value && rawUrl.value
|
||||||
? getStaticImageUrl(rawUrl.value)
|
? getStaticImageUrl(rawUrl.value)
|
||||||
: rawUrl.value
|
: rawUrl.value,
|
||||||
);
|
);
|
||||||
|
|
||||||
const alt = computed(() => `:${customEmojiName.value}:`);
|
const alt = computed(() => `:${customEmojiName.value}:`);
|
||||||
|
|
|
@ -2,9 +2,9 @@
|
||||||
<div v-if="show" ref="el" :class="[$style.root]" :style="{ background: bg }">
|
<div v-if="show" ref="el" :class="[$style.root]" :style="{ background: bg }">
|
||||||
<div :class="[$style.upper, { [$style.slim]: narrow, [$style.thin]: thin_ }]">
|
<div :class="[$style.upper, { [$style.slim]: narrow, [$style.thin]: thin_ }]">
|
||||||
<div v-if="!thin_ && narrow && props.displayMyAvatar && $i" class="_button" :class="$style.buttonsLeft" @click="openAccountMenu">
|
<div v-if="!thin_ && narrow && props.displayMyAvatar && $i" class="_button" :class="$style.buttonsLeft" @click="openAccountMenu">
|
||||||
<MkAvatar :class="$style.avatar" :user="$i" />
|
<MkAvatar :class="$style.avatar" :user="$i"/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="!thin_ && narrow && !hideTitle" :class="$style.buttonsLeft" />
|
<div v-else-if="!thin_ && narrow && !hideTitle" :class="$style.buttonsLeft"/>
|
||||||
|
|
||||||
<template v-if="metadata">
|
<template v-if="metadata">
|
||||||
<div v-if="!hideTitle" :class="$style.titleContainer" @click="top">
|
<div v-if="!hideTitle" :class="$style.titleContainer" @click="top">
|
||||||
|
@ -36,11 +36,11 @@
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted, onUnmounted, ref, inject } from 'vue';
|
import { onMounted, onUnmounted, ref, inject } from 'vue';
|
||||||
import tinycolor from 'tinycolor2';
|
import tinycolor from 'tinycolor2';
|
||||||
|
import XTabs, { Tab } from './MkPageHeader.tabs.vue';
|
||||||
import { scrollToTop } from '@/scripts/scroll';
|
import { scrollToTop } from '@/scripts/scroll';
|
||||||
import { globalEvents } from '@/events';
|
import { globalEvents } from '@/events';
|
||||||
import { injectPageMetadata } from '@/scripts/page-metadata';
|
import { injectPageMetadata } from '@/scripts/page-metadata';
|
||||||
import { $i, openAccountMenu as openAccountMenu_ } from '@/account';
|
import { $i, openAccountMenu as openAccountMenu_ } from '@/account';
|
||||||
import XTabs, { Tab } from './MkPageHeader.tabs.vue';
|
|
||||||
|
|
||||||
const props = withDefaults(defineProps<{
|
const props = withDefaults(defineProps<{
|
||||||
tabs?: Tab[];
|
tabs?: Tab[];
|
||||||
|
@ -96,7 +96,7 @@ function onTabClick(): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
const calcBg = () => {
|
const calcBg = () => {
|
||||||
const rawBg = metadata?.bg || 'var(--bg)';
|
const rawBg = metadata?.bg ?? 'var(--bg)';
|
||||||
const tinyBg = tinycolor(rawBg.startsWith('var(') ? getComputedStyle(document.documentElement).getPropertyValue(rawBg.slice(4, -1)) : rawBg);
|
const tinyBg = tinycolor(rawBg.startsWith('var(') ? getComputedStyle(document.documentElement).getPropertyValue(rawBg.slice(4, -1)) : rawBg);
|
||||||
tinyBg.setAlpha(0.85);
|
tinyBg.setAlpha(0.85);
|
||||||
bg.value = tinyBg.toRgbString();
|
bg.value = tinyBg.toRgbString();
|
||||||
|
|
|
@ -113,7 +113,7 @@ function onTabClick(tab: Tab, ev: MouseEvent): void {
|
||||||
}
|
}
|
||||||
|
|
||||||
const calcBg = () => {
|
const calcBg = () => {
|
||||||
const rawBg = metadata?.bg || 'var(--bg)';
|
const rawBg = metadata?.bg ?? 'var(--bg)';
|
||||||
const tinyBg = tinycolor(rawBg.startsWith('var(') ? getComputedStyle(document.documentElement).getPropertyValue(rawBg.slice(4, -1)) : rawBg);
|
const tinyBg = tinycolor(rawBg.startsWith('var(') ? getComputedStyle(document.documentElement).getPropertyValue(rawBg.slice(4, -1)) : rawBg);
|
||||||
tinyBg.setAlpha(0.85);
|
tinyBg.setAlpha(0.85);
|
||||||
bg.value = tinyBg.toRgbString();
|
bg.value = tinyBg.toRgbString();
|
||||||
|
|
|
@ -1,12 +1,12 @@
|
||||||
<template>
|
<template>
|
||||||
<MkStickyContainer>
|
<MkStickyContainer>
|
||||||
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs" /></template>
|
<template #header><MkPageHeader :actions="headerActions" :tabs="headerTabs"/></template>
|
||||||
<MkSpacer :content-max="500">
|
<MkSpacer :content-max="500">
|
||||||
<div v-if="state == 'fetch-session-error'">
|
<div v-if="state == 'fetch-session-error'">
|
||||||
<p>{{ i18n.ts.somethingHappened }}</p>
|
<p>{{ i18n.ts.somethingHappened }}</p>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="$i && !session">
|
<div v-else-if="$i && !session">
|
||||||
<MkLoading />
|
<MkLoading/>
|
||||||
</div>
|
</div>
|
||||||
<div v-else-if="$i && session">
|
<div v-else-if="$i && session">
|
||||||
<XForm
|
<XForm
|
||||||
|
@ -21,15 +21,16 @@
|
||||||
</div>
|
</div>
|
||||||
<div v-if="state == 'accepted' && session">
|
<div v-if="state == 'accepted' && session">
|
||||||
<h1>{{ session.app.isAuthorized ? $t('already-authorized') : i18n.ts.allowed }}</h1>
|
<h1>{{ session.app.isAuthorized ? $t('already-authorized') : i18n.ts.allowed }}</h1>
|
||||||
<p v-if="session.app.callbackUrl">{{ i18n.ts._auth.callback }}
|
<p v-if="session.app.callbackUrl">
|
||||||
<MkEllipsis />
|
{{ i18n.ts._auth.callback }}
|
||||||
|
<MkEllipsis/>
|
||||||
</p>
|
</p>
|
||||||
<p v-if="!session.app.callbackUrl">{{ i18n.ts._auth.pleaseGoBack }}</p>
|
<p v-if="!session.app.callbackUrl">{{ i18n.ts._auth.pleaseGoBack }}</p>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div v-else>
|
<div v-else>
|
||||||
<p :class="$style.loginMessage">{{ i18n.ts._auth.pleaseLogin }}</p>
|
<p :class="$style.loginMessage">{{ i18n.ts._auth.pleaseLogin }}</p>
|
||||||
<MkSignin @login="onLogin" />
|
<MkSignin @login="onLogin"/>
|
||||||
</div>
|
</div>
|
||||||
</MkSpacer>
|
</MkSpacer>
|
||||||
</MkStickyContainer>
|
</MkStickyContainer>
|
||||||
|
@ -37,12 +38,12 @@
|
||||||
|
|
||||||
<script lang="ts" setup>
|
<script lang="ts" setup>
|
||||||
import { onMounted } from 'vue';
|
import { onMounted } from 'vue';
|
||||||
|
import { AuthSession } from 'misskey-js/built/entities';
|
||||||
import XForm from './auth.form.vue';
|
import XForm from './auth.form.vue';
|
||||||
import MkSignin from '@/components/MkSignin.vue';
|
import MkSignin from '@/components/MkSignin.vue';
|
||||||
import * as os from '@/os';
|
import * as os from '@/os';
|
||||||
import { $i, login } from '@/account';
|
import { $i, login } from '@/account';
|
||||||
import { definePageMetadata } from '@/scripts/page-metadata';
|
import { definePageMetadata } from '@/scripts/page-metadata';
|
||||||
import { AuthSession } from 'misskey-js/built/entities';
|
|
||||||
import { i18n } from '@/i18n';
|
import { i18n } from '@/i18n';
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
|
@ -82,7 +83,7 @@ onMounted(async () => {
|
||||||
} else {
|
} else {
|
||||||
state = 'waiting';
|
state = 'waiting';
|
||||||
}
|
}
|
||||||
} catch (e) {
|
} catch (err) {
|
||||||
state = 'fetch-session-error';
|
state = 'fetch-session-error';
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
|
@ -124,11 +124,11 @@ function saveFields() {
|
||||||
|
|
||||||
function save() {
|
function save() {
|
||||||
os.apiWithDialog('i/update', {
|
os.apiWithDialog('i/update', {
|
||||||
name: profile.name || null,
|
name: profile.name ?? null,
|
||||||
description: profile.description || null,
|
description: profile.description ?? null,
|
||||||
location: profile.location || null,
|
location: profile.location ?? null,
|
||||||
birthday: profile.birthday || null,
|
birthday: profile.birthday ?? null,
|
||||||
lang: profile.lang || null,
|
lang: profile.lang ?? null,
|
||||||
isBot: !!profile.isBot,
|
isBot: !!profile.isBot,
|
||||||
isCat: !!profile.isCat,
|
isCat: !!profile.isCat,
|
||||||
showTimelineReplies: !!profile.showTimelineReplies,
|
showTimelineReplies: !!profile.showTimelineReplies,
|
||||||
|
|
|
@ -48,8 +48,8 @@ export class Storage<T extends StateDef> {
|
||||||
// 簡易的にキューイングして占有ロックとする
|
// 簡易的にキューイングして占有ロックとする
|
||||||
private currentIdbJob: Promise<any> = Promise.resolve();
|
private currentIdbJob: Promise<any> = Promise.resolve();
|
||||||
private addIdbSetJob<T>(job: () => Promise<T>) {
|
private addIdbSetJob<T>(job: () => Promise<T>) {
|
||||||
const promise = this.currentIdbJob.then(job, e => {
|
const promise = this.currentIdbJob.then(job, err => {
|
||||||
console.error('Pizzax failed to save data to idb!', e);
|
console.error('Pizzax failed to save data to idb!', err);
|
||||||
return job();
|
return job();
|
||||||
});
|
});
|
||||||
this.currentIdbJob = promise;
|
this.currentIdbJob = promise;
|
||||||
|
@ -130,22 +130,22 @@ export class Storage<T extends StateDef> {
|
||||||
await defaultStore.ready;
|
await defaultStore.ready;
|
||||||
|
|
||||||
api('i/registry/get-all', { scope: ['client', this.key] })
|
api('i/registry/get-all', { scope: ['client', this.key] })
|
||||||
.then(kvs => {
|
.then(kvs => {
|
||||||
const cache: Partial<T> = {};
|
const cache: Partial<T> = {};
|
||||||
for (const [k, v] of Object.entries(this.def) as [keyof T, T[keyof T]['default']][]) {
|
for (const [k, v] of Object.entries(this.def) as [keyof T, T[keyof T]['default']][]) {
|
||||||
if (v.where === 'account') {
|
if (v.where === 'account') {
|
||||||
if (Object.prototype.hasOwnProperty.call(kvs, k)) {
|
if (Object.prototype.hasOwnProperty.call(kvs, k)) {
|
||||||
this.reactiveState[k].value = this.state[k] = (kvs as Partial<T>)[k];
|
this.reactiveState[k].value = this.state[k] = (kvs as Partial<T>)[k];
|
||||||
cache[k] = (kvs as Partial<T>)[k];
|
cache[k] = (kvs as Partial<T>)[k];
|
||||||
} else {
|
} else {
|
||||||
this.reactiveState[k].value = this.state[k] = v.default;
|
this.reactiveState[k].value = this.state[k] = v.default;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
return set(this.registryCacheKeyName, cache);
|
return set(this.registryCacheKeyName, cache);
|
||||||
})
|
})
|
||||||
.then(() => resolve());
|
.then(() => resolve());
|
||||||
}, 1);
|
}, 1);
|
||||||
} else {
|
} else {
|
||||||
resolve();
|
resolve();
|
||||||
|
|
|
@ -240,7 +240,7 @@ export function getNoteMenu(props: {
|
||||||
icon: 'ti ti-external-link',
|
icon: 'ti ti-external-link',
|
||||||
text: i18n.ts.showOnRemote,
|
text: i18n.ts.showOnRemote,
|
||||||
action: () => {
|
action: () => {
|
||||||
window.open(appearNote.url || appearNote.uri, '_blank');
|
window.open(appearNote.url ?? appearNote.uri, '_blank');
|
||||||
},
|
},
|
||||||
} : undefined,
|
} : undefined,
|
||||||
{
|
{
|
||||||
|
@ -302,7 +302,7 @@ export function getNoteMenu(props: {
|
||||||
icon: 'ti ti-exclamation-circle',
|
icon: 'ti ti-exclamation-circle',
|
||||||
text: i18n.ts.reportAbuse,
|
text: i18n.ts.reportAbuse,
|
||||||
action: () => {
|
action: () => {
|
||||||
const u = appearNote.url || appearNote.uri || `${url}/notes/${appearNote.id}`;
|
const u = appearNote.url ?? appearNote.uri ?? `${url}/notes/${appearNote.id}`;
|
||||||
os.popup(defineAsyncComponent(() => import('@/components/MkAbuseReportWindow.vue')), {
|
os.popup(defineAsyncComponent(() => import('@/components/MkAbuseReportWindow.vue')), {
|
||||||
user: appearNote.user,
|
user: appearNote.user,
|
||||||
initialComment: `Note: ${u}\n-----\n`,
|
initialComment: `Note: ${u}\n-----\n`,
|
||||||
|
@ -344,7 +344,7 @@ export function getNoteMenu(props: {
|
||||||
icon: 'ti ti-external-link',
|
icon: 'ti ti-external-link',
|
||||||
text: i18n.ts.showOnRemote,
|
text: i18n.ts.showOnRemote,
|
||||||
action: () => {
|
action: () => {
|
||||||
window.open(appearNote.url || appearNote.uri, '_blank');
|
window.open(appearNote.url ?? appearNote.uri, '_blank');
|
||||||
},
|
},
|
||||||
} : undefined]
|
} : undefined]
|
||||||
.filter(x => x !== undefined);
|
.filter(x => x !== undefined);
|
||||||
|
|
|
@ -58,7 +58,7 @@ export class HpmlScope {
|
||||||
|
|
||||||
constructor(layerdStates: HpmlScope['layerdStates'], name?: HpmlScope['name']) {
|
constructor(layerdStates: HpmlScope['layerdStates'], name?: HpmlScope['name']) {
|
||||||
this.layerdStates = layerdStates;
|
this.layerdStates = layerdStates;
|
||||||
this.name = name || 'anonymous';
|
this.name = name ?? 'anonymous';
|
||||||
}
|
}
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
|
|
|
@ -63,7 +63,7 @@ export class HpmlTypeChecker {
|
||||||
|
|
||||||
@autobind
|
@autobind
|
||||||
public getExpectedType(v: Expr, slot: number): Type {
|
public getExpectedType(v: Expr, slot: number): Type {
|
||||||
const def = funcDefs[v.type || ''];
|
const def = funcDefs[v.type ?? ''];
|
||||||
if (def == null) {
|
if (def == null) {
|
||||||
throw new Error('Unknown type: ' + v.type);
|
throw new Error('Unknown type: ' + v.type);
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ export class HpmlTypeChecker {
|
||||||
return pageVar.type;
|
return pageVar.type;
|
||||||
}
|
}
|
||||||
|
|
||||||
const envVar = envVarsDef[v.value || ''];
|
const envVar = envVarsDef[v.value ?? ''];
|
||||||
if (envVar !== undefined) {
|
if (envVar !== undefined) {
|
||||||
return envVar;
|
return envVar;
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,7 +10,7 @@ export function getScrollContainer(el: HTMLElement | null): HTMLElement | null {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getStickyTop(el: HTMLElement, container: HTMLElement | null = null, top: number = 0) {
|
export function getStickyTop(el: HTMLElement, container: HTMLElement | null = null, top = 0) {
|
||||||
if (!el.parentElement) return top;
|
if (!el.parentElement) return top;
|
||||||
const data = el.dataset.stickyContainerHeaderHeight;
|
const data = el.dataset.stickyContainerHeaderHeight;
|
||||||
const newTop = data ? Number(data) + top : top;
|
const newTop = data ? Number(data) + top : top;
|
||||||
|
@ -23,14 +23,14 @@ export function getScrollPosition(el: HTMLElement | null): number {
|
||||||
return container == null ? window.scrollY : container.scrollTop;
|
return container == null ? window.scrollY : container.scrollTop;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function onScrollTop(el: HTMLElement, cb: () => unknown, tolerance: number = 1, once: boolean = false) {
|
export function onScrollTop(el: HTMLElement, cb: () => unknown, tolerance = 1, once = false) {
|
||||||
// とりあえず評価してみる
|
// とりあえず評価してみる
|
||||||
if (isTopVisible(el)) {
|
if (isTopVisible(el)) {
|
||||||
cb();
|
cb();
|
||||||
if (once) return null;
|
if (once) return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const container = getScrollContainer(el) || window;
|
const container = getScrollContainer(el) ?? window;
|
||||||
|
|
||||||
const onScroll = ev => {
|
const onScroll = ev => {
|
||||||
if (!document.body.contains(el)) return;
|
if (!document.body.contains(el)) return;
|
||||||
|
@ -45,7 +45,7 @@ export function onScrollTop(el: HTMLElement, cb: () => unknown, tolerance: numbe
|
||||||
return removeListener;
|
return removeListener;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function onScrollBottom(el: HTMLElement, cb: () => unknown, tolerance: number = 1, once: boolean = false) {
|
export function onScrollBottom(el: HTMLElement, cb: () => unknown, tolerance = 1, once = false) {
|
||||||
const container = getScrollContainer(el);
|
const container = getScrollContainer(el);
|
||||||
|
|
||||||
// とりあえず評価してみる
|
// とりあえず評価してみる
|
||||||
|
@ -54,7 +54,7 @@ export function onScrollBottom(el: HTMLElement, cb: () => unknown, tolerance: nu
|
||||||
if (once) return null;
|
if (once) return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
const containerOrWindow = container || window;
|
const containerOrWindow = container ?? window;
|
||||||
const onScroll = ev => {
|
const onScroll = ev => {
|
||||||
if (!document.body.contains(el)) return;
|
if (!document.body.contains(el)) return;
|
||||||
if (isBottomVisible(el, 1, container)) {
|
if (isBottomVisible(el, 1, container)) {
|
||||||
|
@ -104,12 +104,12 @@ export function scrollToBottom(
|
||||||
} else {
|
} else {
|
||||||
window.scroll({
|
window.scroll({
|
||||||
top: (el.scrollHeight - window.innerHeight + getStickyTop(el, container) + (window.innerWidth <= 500 ? 96 : 0)) || 0,
|
top: (el.scrollHeight - window.innerHeight + getStickyTop(el, container) + (window.innerWidth <= 500 ? 96 : 0)) || 0,
|
||||||
...options
|
...options,
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function isTopVisible(el: HTMLElement, tolerance: number = 1): boolean {
|
export function isTopVisible(el: HTMLElement, tolerance = 1): boolean {
|
||||||
const scrollTop = getScrollPosition(el);
|
const scrollTop = getScrollPosition(el);
|
||||||
return scrollTop <= tolerance;
|
return scrollTop <= tolerance;
|
||||||
}
|
}
|
||||||
|
@ -124,6 +124,6 @@ export function getBodyScrollHeight() {
|
||||||
return Math.max(
|
return Math.max(
|
||||||
document.body.scrollHeight, document.documentElement.scrollHeight,
|
document.body.scrollHeight, document.documentElement.scrollHeight,
|
||||||
document.body.offsetHeight, document.documentElement.offsetHeight,
|
document.body.offsetHeight, document.documentElement.offsetHeight,
|
||||||
document.body.clientHeight, document.documentElement.clientHeight
|
document.body.clientHeight, document.documentElement.clientHeight,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,13 +1,13 @@
|
||||||
import { api } from '@/os';
|
|
||||||
import { $i } from '@/account';
|
|
||||||
import { Theme } from './scripts/theme';
|
import { Theme } from './scripts/theme';
|
||||||
import { miLocalStorage } from './local-storage';
|
import { miLocalStorage } from './local-storage';
|
||||||
|
import { api } from '@/os';
|
||||||
|
import { $i } from '@/account';
|
||||||
|
|
||||||
const lsCacheKey = $i ? `themes:${$i.id}` as const : null;
|
const lsCacheKey = $i ? `themes:${$i.id}` as const : null;
|
||||||
|
|
||||||
export function getThemes(): Theme[] {
|
export function getThemes(): Theme[] {
|
||||||
if ($i == null) return [];
|
if ($i == null) return [];
|
||||||
return JSON.parse(miLocalStorage.getItem(lsCacheKey!) || '[]');
|
return JSON.parse(miLocalStorage.getItem(lsCacheKey!) ?? '[]');
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function fetchThemes(): Promise<void> {
|
export async function fetchThemes(): Promise<void> {
|
||||||
|
|
|
@ -125,7 +125,7 @@ function onAiClick(ev) {
|
||||||
|
|
||||||
if (window.innerWidth < 1024) {
|
if (window.innerWidth < 1024) {
|
||||||
const currentUI = miLocalStorage.getItem('ui');
|
const currentUI = miLocalStorage.getItem('ui');
|
||||||
miLocalStorage.setItem('ui_temp', currentUI || 'default');
|
miLocalStorage.setItem('ui_temp', currentUI ?? 'default');
|
||||||
miLocalStorage.setItem('ui', 'default');
|
miLocalStorage.setItem('ui', 'default');
|
||||||
location.reload();
|
location.reload();
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,3 @@
|
||||||
export default function(user: { name?: string | null, username: string }): string {
|
export default function(user: { name?: string | null, username: string }): string {
|
||||||
// Show username if name is empty.
|
return user.name === '' ? user.username : user.name ?? user.username;
|
||||||
// XXX: typescript-eslint has no configuration to allow using `||` against string.
|
|
||||||
// https://github.com/typescript-eslint/typescript-eslint/issues/4906
|
|
||||||
// eslint-disable-next-line @typescript-eslint/prefer-nullish-coalescing
|
|
||||||
return user.name || user.username;
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue