refactor (client): use ?? to check null/undefined
This commit is contained in:
parent
be726a45f9
commit
1aec738200
93 changed files with 267 additions and 267 deletions
|
@ -55,7 +55,7 @@ export async function signout() {
|
|||
export async function getAccounts(): Promise<
|
||||
{ id: Account["id"]; token: Account["token"] }[]
|
||||
> {
|
||||
return (await get("accounts")) || [];
|
||||
return (await get("accounts")) ?? [];
|
||||
}
|
||||
|
||||
export async function addAccount(id: Account["id"], token: Account["token"]) {
|
||||
|
|
|
@ -59,7 +59,7 @@ const emit = defineEmits<{
|
|||
}>();
|
||||
|
||||
const uiWindow = ref<InstanceType<typeof XWindow>>();
|
||||
const comment = ref(props.initialComment || "");
|
||||
const comment = ref(props.initialComment ?? "");
|
||||
|
||||
function send() {
|
||||
os.apiWithDialog(
|
||||
|
|
|
@ -268,7 +268,7 @@ function exec() {
|
|||
} else if (props.type === "hashtag") {
|
||||
if (!props.q || props.q === "") {
|
||||
hashtags.value = JSON.parse(
|
||||
localStorage.getItem("hashtags") || "[]",
|
||||
localStorage.getItem("hashtags") ?? "[]",
|
||||
);
|
||||
fetching.value = false;
|
||||
} else {
|
||||
|
|
|
@ -78,14 +78,14 @@ const src = computed(() => {
|
|||
});
|
||||
|
||||
const captcha = computed<Captcha>(
|
||||
() => window[variable.value] || ({} as unknown as Captcha),
|
||||
() => window[variable.value] ?? ({} as Captcha),
|
||||
);
|
||||
|
||||
if (loaded) {
|
||||
available.value = true;
|
||||
} else {
|
||||
(
|
||||
document.getElementById(props.provider) ||
|
||||
document.getElementById(props.provider) ??
|
||||
document.head.appendChild(
|
||||
Object.assign(document.createElement("script"), {
|
||||
async: true,
|
||||
|
|
|
@ -50,7 +50,7 @@ export default defineComponent({
|
|||
|
||||
const renderChildren = () =>
|
||||
props.items.map((item, i) => {
|
||||
if (!slots || !slots.default) return;
|
||||
if (slots == null || slots.default == null) return;
|
||||
|
||||
const el = slots.default({
|
||||
item,
|
||||
|
|
|
@ -65,8 +65,10 @@
|
|||
v-model="inputValue"
|
||||
autofocus
|
||||
:autocomplete="input.autocomplete"
|
||||
:type="input.type == 'search' ? 'search' : input.type || 'text'"
|
||||
:placeholder="input.placeholder || undefined"
|
||||
:type="
|
||||
input.type === 'search' ? 'search' : input.type ?? 'text'
|
||||
"
|
||||
:placeholder="input.placeholder ?? undefined"
|
||||
:style="{
|
||||
width: input.type === 'search' ? '300px' : null,
|
||||
}"
|
||||
|
@ -294,7 +296,7 @@ const okButtonDisabled = computed<boolean>(() => {
|
|||
if (props.input) {
|
||||
if (props.input.minLength) {
|
||||
if (
|
||||
(inputValue.value || inputValue.value === "") &&
|
||||
inputValue.value != null &&
|
||||
(inputValue.value as string).length < props.input.minLength
|
||||
) {
|
||||
disabledReason.value = "charactersBelow";
|
||||
|
|
|
@ -185,7 +185,7 @@ function describe() {
|
|||
},
|
||||
{
|
||||
done: (result) => {
|
||||
if (!result || result.canceled) return;
|
||||
if (result == null || result.canceled) return;
|
||||
const comment = result.result;
|
||||
os.api("drive/files/update", {
|
||||
fileId: props.file.id,
|
||||
|
|
|
@ -363,7 +363,7 @@ function urlUpload() {
|
|||
type: "url",
|
||||
placeholder: i18n.ts.uploadFromUrlDescription,
|
||||
}).then(({ canceled, result: url }) => {
|
||||
if (canceled || !url) return;
|
||||
if (canceled || url == null) return;
|
||||
os.api("drive/files/upload-from-url", {
|
||||
url,
|
||||
folderId: folder.value ? folder.value.id : undefined,
|
||||
|
|
|
@ -106,7 +106,7 @@
|
|||
.map((e) => ':' + e.name + ':')
|
||||
"
|
||||
@chosen="chosen"
|
||||
>{{ category || i18n.ts.other }}</XSection
|
||||
>{{ category ?? i18n.ts.other }}</XSection
|
||||
>
|
||||
</div>
|
||||
<div v-once class="group">
|
||||
|
@ -423,7 +423,7 @@ function reset() {
|
|||
function getKey(
|
||||
emoji: string | firefish.entities.CustomEmoji | UnicodeEmojiDef,
|
||||
): string {
|
||||
return typeof emoji === "string" ? emoji : emoji.emoji || `:${emoji.name}:`;
|
||||
return typeof emoji === "string" ? emoji : emoji.emoji ?? `:${emoji.name}:`;
|
||||
}
|
||||
|
||||
function chosen(emoji: any, ev?: MouseEvent) {
|
||||
|
@ -450,7 +450,7 @@ function chosen(emoji: any, ev?: MouseEvent) {
|
|||
}
|
||||
|
||||
function paste(event: ClipboardEvent) {
|
||||
const paste = (event.clipboardData || window.clipboardData).getData("text");
|
||||
const paste = (event.clipboardData ?? window.clipboardData).getData("text");
|
||||
if (done(paste)) {
|
||||
event.preventDefault();
|
||||
}
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
</button>
|
||||
<button
|
||||
v-if="!hideFollowButton && isSignedIn && $i.id != user.id"
|
||||
v-tooltip="full ? null : `${state} ${user.name || user.username}`"
|
||||
v-tooltip="full ? null : `${state} ${user.name ?? user.username}`"
|
||||
class="kpoogebi _button follow-button"
|
||||
:class="{
|
||||
wait,
|
||||
|
@ -19,7 +19,7 @@
|
|||
blocking: isBlocking,
|
||||
}"
|
||||
:disabled="wait"
|
||||
:aria-label="`${state} ${user.name || user.username}`"
|
||||
:aria-label="`${state} ${user.name ?? user.username}`"
|
||||
@click.stop="onClick"
|
||||
>
|
||||
<template v-if="!wait">
|
||||
|
@ -141,7 +141,7 @@ async function onClick() {
|
|||
const { canceled } = await os.confirm({
|
||||
type: "warning",
|
||||
text: i18n.t("unfollowConfirm", {
|
||||
name: props.user.name || props.user.username,
|
||||
name: props.user.name ?? props.user.username,
|
||||
}),
|
||||
});
|
||||
|
||||
|
|
|
@ -25,11 +25,11 @@
|
|||
v-if="form[item].type === 'number'"
|
||||
v-model="values[item]"
|
||||
type="number"
|
||||
:step="form[item].step || 1"
|
||||
:step="form[item].step ?? 1"
|
||||
class="_formBlock"
|
||||
>
|
||||
<template #label
|
||||
><span v-text="form[item].label || item"></span
|
||||
><span v-text="form[item].label ?? item"></span
|
||||
><span v-if="form[item].required === false">
|
||||
({{ i18n.ts.optional }})</span
|
||||
></template
|
||||
|
@ -48,7 +48,7 @@
|
|||
class="_formBlock"
|
||||
>
|
||||
<template #label
|
||||
><span v-text="form[item].label || item"></span
|
||||
><span v-text="form[item].label ?? item"></span
|
||||
><span v-if="form[item].required === false">
|
||||
({{ i18n.ts.optional }})</span
|
||||
></template
|
||||
|
@ -65,7 +65,7 @@
|
|||
class="_formBlock"
|
||||
>
|
||||
<template #label
|
||||
><span v-text="form[item].label || item"></span
|
||||
><span v-text="form[item].label ?? item"></span
|
||||
><span v-if="form[item].required === false">
|
||||
({{ i18n.ts.optional }})</span
|
||||
></template
|
||||
|
@ -79,7 +79,7 @@
|
|||
v-model="values[item]"
|
||||
class="_formBlock"
|
||||
>
|
||||
<span v-text="form[item].label || item"></span>
|
||||
<span v-text="form[item].label ?? item"></span>
|
||||
<template v-if="form[item].description" #caption>{{
|
||||
form[item].description
|
||||
}}</template>
|
||||
|
@ -90,7 +90,7 @@
|
|||
class="_formBlock"
|
||||
>
|
||||
<template #label
|
||||
><span v-text="form[item].label || item"></span
|
||||
><span v-text="form[item].label ?? item"></span
|
||||
><span v-if="form[item].required === false">
|
||||
({{ i18n.ts.optional }})</span
|
||||
></template
|
||||
|
@ -109,7 +109,7 @@
|
|||
class="_formBlock"
|
||||
>
|
||||
<template #label
|
||||
><span v-text="form[item].label || item"></span
|
||||
><span v-text="form[item].label ?? item"></span
|
||||
><span v-if="form[item].required === false">
|
||||
({{ i18n.ts.optional }})</span
|
||||
></template
|
||||
|
@ -132,7 +132,7 @@
|
|||
class="_formBlock"
|
||||
>
|
||||
<template #label
|
||||
><span v-text="form[item].label || item"></span
|
||||
><span v-text="form[item].label ?? item"></span
|
||||
><span v-if="form[item].required === false">
|
||||
({{ i18n.ts.optional }})</span
|
||||
></template
|
||||
|
@ -146,7 +146,7 @@
|
|||
class="_formBlock"
|
||||
@click="form[item].action($event, values)"
|
||||
>
|
||||
<span v-text="form[item].content || item"></span>
|
||||
<span v-text="form[item].content ?? item"></span>
|
||||
</MkButton>
|
||||
</template>
|
||||
</div>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<span class="host">{{ instance.name ?? instance.host }}</span>
|
||||
<span class="sub _monospace"
|
||||
><b>{{ instance.host }}</b> /
|
||||
{{ instance.softwareName || "?" }}
|
||||
{{ instance.softwareName ?? "?" }}
|
||||
{{ instance.softwareVersion }}</span
|
||||
>
|
||||
</div>
|
||||
|
|
|
@ -33,7 +33,7 @@ const ticker = ref<HTMLElement | null>(null);
|
|||
|
||||
// if no instance data is given, this is for the local instance
|
||||
const instance = props.instance ?? {
|
||||
faviconUrl: Instance.faviconUrl || Instance.iconUrl || "/favicon.ico",
|
||||
faviconUrl: Instance.faviconUrl ?? Instance.iconUrl ?? "/favicon.ico",
|
||||
name: instanceName,
|
||||
themeColor: (
|
||||
document.querySelector(
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<span class="main">
|
||||
<span class="username">@{{ username }}</span>
|
||||
<span
|
||||
v-if="host != localHost || defaultStore.state.showFullAcct"
|
||||
v-if="host !== localHost || defaultStore.state.showFullAcct"
|
||||
class="host"
|
||||
>@{{ toUnicode(host) }}</span
|
||||
>
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
<template v-for="item in items2">
|
||||
<div v-if="item === null" class="divider"></div>
|
||||
<span v-else-if="item.type === 'label'" class="label item">
|
||||
<span :style="item.textStyle || ''">{{
|
||||
<span :style="item.textStyle ?? ''">{{
|
||||
item.text
|
||||
}}</span>
|
||||
</span>
|
||||
|
@ -50,7 +50,7 @@
|
|||
class="avatar"
|
||||
disable-link
|
||||
/>
|
||||
<span :style="item.textStyle || ''">{{
|
||||
<span :style="item.textStyle ?? ''">{{
|
||||
item.text
|
||||
}}</span>
|
||||
<span
|
||||
|
@ -76,7 +76,7 @@
|
|||
v-if="item.icon"
|
||||
:class="icon(`${item.icon} ph-fw`)"
|
||||
></i>
|
||||
<span :style="item.textStyle || ''">{{
|
||||
<span :style="item.textStyle ?? ''">{{
|
||||
item.text
|
||||
}}</span>
|
||||
<span
|
||||
|
@ -121,7 +121,7 @@
|
|||
v-model="item.ref"
|
||||
:disabled="item.disabled"
|
||||
class="form-switch"
|
||||
:style="item.textStyle || ''"
|
||||
:style="item.textStyle ?? ''"
|
||||
>{{ item.text }}</FormSwitch
|
||||
>
|
||||
</span>
|
||||
|
@ -136,7 +136,7 @@
|
|||
v-if="item.icon"
|
||||
:class="icon(`${item.icon} ph-fw`)"
|
||||
></i>
|
||||
<span :style="item.textStyle || ''">{{
|
||||
<span :style="item.textStyle ?? ''">{{
|
||||
item.text
|
||||
}}</span>
|
||||
<span class="caret"
|
||||
|
@ -166,7 +166,7 @@
|
|||
class="avatar"
|
||||
disable-link
|
||||
/>
|
||||
<span :style="item.textStyle || ''">{{
|
||||
<span :style="item.textStyle ?? ''">{{
|
||||
item.text
|
||||
}}</span>
|
||||
<span
|
||||
|
|
|
@ -48,7 +48,7 @@ const color = accent.toRgbString();
|
|||
|
||||
function draw(): void {
|
||||
const stats = props.src.slice().reverse();
|
||||
const peak = Math.max.apply(null, stats) || 1;
|
||||
const peak = Math.max(1, ...stats);
|
||||
|
||||
const _polylinePoints = stats.map((n, i) => [
|
||||
i * (viewBoxX / (stats.length - 1)),
|
||||
|
|
|
@ -375,7 +375,7 @@ const isForeignLanguage: boolean =
|
|||
defaultStore.state.detectPostLanguage &&
|
||||
appearNote.value.text != null &&
|
||||
(() => {
|
||||
const targetLang = (translateLang || lang || navigator.language)?.slice(
|
||||
const targetLang = (translateLang ?? lang ?? navigator.language)?.slice(
|
||||
0,
|
||||
2,
|
||||
);
|
||||
|
@ -395,7 +395,7 @@ async function translate() {
|
|||
translating.value = true;
|
||||
translation.value = await translate_(
|
||||
appearNote.value.id,
|
||||
translateLang || lang || navigator.language,
|
||||
translateLang ?? lang ?? navigator.language,
|
||||
);
|
||||
|
||||
// use UI language as the second translation language
|
||||
|
@ -403,7 +403,7 @@ async function translate() {
|
|||
translateLang != null &&
|
||||
lang != null &&
|
||||
translateLang !== lang &&
|
||||
(!translation.value ||
|
||||
(translation.value == null ||
|
||||
translation.value.sourceLang.toLowerCase() ===
|
||||
translateLang.slice(0, 2))
|
||||
)
|
||||
|
|
|
@ -292,7 +292,7 @@ const isForeignLanguage: boolean =
|
|||
defaultStore.state.detectPostLanguage &&
|
||||
appearNote.value.text != null &&
|
||||
(() => {
|
||||
const targetLang = (translateLang || lang || navigator.language)?.slice(
|
||||
const targetLang = (translateLang ?? lang ?? navigator.language)?.slice(
|
||||
0,
|
||||
2,
|
||||
);
|
||||
|
@ -312,7 +312,7 @@ async function translate() {
|
|||
translating.value = true;
|
||||
translation.value = await translate_(
|
||||
appearNote.value.id,
|
||||
translateLang || lang || navigator.language,
|
||||
translateLang ?? lang ?? navigator.language,
|
||||
);
|
||||
|
||||
// use UI language as the second translation language
|
||||
|
@ -320,7 +320,7 @@ async function translate() {
|
|||
translateLang != null &&
|
||||
lang != null &&
|
||||
translateLang !== lang &&
|
||||
(!translation.value ||
|
||||
(translation.value == null ||
|
||||
translation.value.sourceLang.toLowerCase() ===
|
||||
translateLang.slice(0, 2))
|
||||
)
|
||||
|
|
|
@ -28,7 +28,7 @@
|
|||
class="notes"
|
||||
>
|
||||
<XNote
|
||||
:key="note._featuredId_ || note._prId_ || note.id"
|
||||
:key="note._featuredId_ ?? note._prId_ ?? note.id"
|
||||
class="qtqtichx"
|
||||
:note="note"
|
||||
/>
|
||||
|
|
|
@ -64,7 +64,7 @@ const props = withDefaults(
|
|||
},
|
||||
);
|
||||
|
||||
const includingTypes = computed(() => props.includingTypes || []);
|
||||
const includingTypes = computed(() => props.includingTypes ?? []);
|
||||
|
||||
const dialog = ref<InstanceType<typeof XModalWindow>>();
|
||||
|
||||
|
|
|
@ -181,7 +181,7 @@ onMounted(() => {
|
|||
}
|
||||
for (
|
||||
let i = 0;
|
||||
i < (pagingComponent.value.items || []).length;
|
||||
i < (pagingComponent.value.items ?? []).length;
|
||||
i++
|
||||
) {
|
||||
if (
|
||||
|
|
|
@ -18,7 +18,7 @@ const tweened = reactive({
|
|||
watch(
|
||||
() => props.value,
|
||||
(n) => {
|
||||
gsap.to(tweened, { duration: 0.6, number: Number(n) || 0 });
|
||||
gsap.to(tweened, { duration: 0.6, number: Number(n) ?? 0 });
|
||||
},
|
||||
{
|
||||
immediate: true,
|
||||
|
|
|
@ -151,8 +151,8 @@ const init = async (): Promise<void> => {
|
|||
.api(props.pagination.endpoint, {
|
||||
...params,
|
||||
limit: props.pagination.noPaging
|
||||
? props.pagination.limit || 10
|
||||
: (props.pagination.limit || 10) + 1,
|
||||
? props.pagination.limit ?? 10
|
||||
: (props.pagination.limit ?? 10) + 1,
|
||||
})
|
||||
.then(
|
||||
(res) => {
|
||||
|
|
|
@ -389,7 +389,7 @@ const draghover = ref(false);
|
|||
const quoteId = ref(null);
|
||||
const hasNotSpecifiedMentions = ref(false);
|
||||
const recentHashtags = ref(
|
||||
JSON.parse(localStorage.getItem("hashtags") || "[]"),
|
||||
JSON.parse(localStorage.getItem("hashtags") ?? "[]"),
|
||||
);
|
||||
const imeText = ref("");
|
||||
|
||||
|
@ -460,10 +460,10 @@ const canPost = computed((): boolean => {
|
|||
!posting.value &&
|
||||
(textLength.value >= 1 ||
|
||||
files.value.length >= 1 ||
|
||||
!!poll.value ||
|
||||
!!props.renote) &&
|
||||
poll.value != null ||
|
||||
props.renote != null) &&
|
||||
textLength.value <= maxTextLength.value &&
|
||||
(!poll.value || poll.value.choices.length >= 2)
|
||||
(poll.value == null || poll.value.choices.length >= 2)
|
||||
);
|
||||
});
|
||||
|
||||
|
@ -970,7 +970,7 @@ function onDrop(ev): void {
|
|||
}
|
||||
|
||||
function saveDraft() {
|
||||
const draftData = JSON.parse(localStorage.getItem("drafts") || "{}");
|
||||
const draftData = JSON.parse(localStorage.getItem("drafts") ?? "{}");
|
||||
|
||||
draftData[draftKey.value] = {
|
||||
updatedAt: new Date(),
|
||||
|
@ -990,7 +990,7 @@ function saveDraft() {
|
|||
}
|
||||
|
||||
function deleteDraft() {
|
||||
const draftData = JSON.parse(localStorage.getItem("drafts") || "{}");
|
||||
const draftData = JSON.parse(localStorage.getItem("drafts") ?? "{}");
|
||||
|
||||
delete draftData[draftKey.value];
|
||||
|
||||
|
@ -1013,7 +1013,7 @@ async function post() {
|
|||
: undefined,
|
||||
channelId: props.channel ? props.channel.id : undefined,
|
||||
poll: poll.value,
|
||||
cw: useCw.value ? cw.value || "" : undefined,
|
||||
cw: useCw.value ? cw.value ?? "" : undefined,
|
||||
lang: language.value ? language.value : undefined,
|
||||
localOnly: localOnly.value,
|
||||
visibility:
|
||||
|
@ -1065,7 +1065,7 @@ async function post() {
|
|||
.filter((x) => x.type === "hashtag")
|
||||
.map((x) => x.props.hashtag);
|
||||
const history = JSON.parse(
|
||||
localStorage.getItem("hashtags") || "[]",
|
||||
localStorage.getItem("hashtags") ?? "[]",
|
||||
) as string[];
|
||||
localStorage.setItem(
|
||||
"hashtags",
|
||||
|
@ -1184,7 +1184,7 @@ onMounted(() => {
|
|||
autosize(textareaEl.value);
|
||||
// 書きかけの投稿を復元
|
||||
if (!props.instant && !props.mention && !props.specified) {
|
||||
const draft = JSON.parse(localStorage.getItem("drafts") || "{}")[
|
||||
const draft = JSON.parse(localStorage.getItem("drafts") ?? "{}")[
|
||||
draftKey.value
|
||||
];
|
||||
if (draft) {
|
||||
|
@ -1194,7 +1194,7 @@ onMounted(() => {
|
|||
visibility.value = draft.data.visibility;
|
||||
localOnly.value = draft.data.localOnly;
|
||||
language.value = draft.data.lang;
|
||||
files.value = (draft.data.files || []).filter(
|
||||
files.value = (draft.data.files ?? []).filter(
|
||||
(draftFile) => draftFile,
|
||||
);
|
||||
if (draft.data.poll) {
|
||||
|
|
|
@ -105,7 +105,7 @@ async function describe(file) {
|
|||
},
|
||||
{
|
||||
done: (result) => {
|
||||
if (!result || result.canceled) return;
|
||||
if (result == null || result.canceled) return;
|
||||
const comment =
|
||||
result.result.length === 0 ? null : result.result;
|
||||
os.api("drive/files/update", {
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
<template>
|
||||
<MkEmoji
|
||||
:emoji="reaction"
|
||||
:custom-emojis="customEmojis || []"
|
||||
:custom-emojis="customEmojis ?? []"
|
||||
:is-reaction="true"
|
||||
:normal="true"
|
||||
:no-style="noStyle"
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
<template #suffix>@{{ host }}</template>
|
||||
</MkInput>
|
||||
<MkInput
|
||||
v-if="!user || (user && !user.usePasswordLessLogin)"
|
||||
v-if="user == null || (user && !user.usePasswordLessLogin)"
|
||||
v-model="password"
|
||||
class="_formBlock"
|
||||
:placeholder="i18n.ts.password"
|
||||
|
|
|
@ -310,12 +310,12 @@ const host = toUnicode(config.host);
|
|||
const hcaptcha = ref();
|
||||
const recaptcha = ref();
|
||||
|
||||
const username: string = ref("");
|
||||
const password: string = ref("");
|
||||
const retypedPassword: string = ref("");
|
||||
const invitationCode: string = ref("");
|
||||
const username = ref("");
|
||||
const password = ref("");
|
||||
const retypedPassword = ref("");
|
||||
const invitationCode = ref("");
|
||||
const email = ref("");
|
||||
const usernameState:
|
||||
const usernameState = ref<
|
||||
| null
|
||||
| "wait"
|
||||
| "ok"
|
||||
|
@ -323,9 +323,10 @@ const usernameState:
|
|||
| "error"
|
||||
| "invalid-format"
|
||||
| "min-range"
|
||||
| "max-range" = ref(null);
|
||||
const invitationState: null | "entered" = ref(null);
|
||||
const emailState:
|
||||
| "max-range"
|
||||
>(null);
|
||||
const invitationState = ref<null | "entered">(null);
|
||||
const emailState = ref<
|
||||
| null
|
||||
| "wait"
|
||||
| "ok"
|
||||
|
@ -335,11 +336,12 @@ const emailState:
|
|||
| "unavailable:mx"
|
||||
| "unavailable:smtp"
|
||||
| "unavailable"
|
||||
| "error" = ref(null);
|
||||
const passwordStrength: "" | "low" | "medium" | "high" = ref("");
|
||||
const passwordRetypeState: null | "match" | "not-match" = ref(null);
|
||||
const submitting: boolean = ref(false);
|
||||
const ToSAgreement: boolean = ref(false);
|
||||
| "error"
|
||||
>(null);
|
||||
const passwordStrength = ref<"" | "low" | "medium" | "high">("");
|
||||
const passwordRetypeState = ref<null | "match" | "not-match">(null);
|
||||
const submitting = ref(false);
|
||||
const ToSAgreement = ref(false);
|
||||
const hCaptchaResponse = ref(null);
|
||||
const reCaptchaResponse = ref(null);
|
||||
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
@closed="$emit('closed')"
|
||||
@ok="ok()"
|
||||
>
|
||||
<template #header>{{ title || i18n.ts.generateAccessToken }}</template>
|
||||
<template #header>{{ title ?? i18n.ts.generateAccessToken }}</template>
|
||||
<div v-if="information" class="_section">
|
||||
<MkInfo warn>{{ information }}</MkInfo>
|
||||
</div>
|
||||
|
@ -32,7 +32,7 @@
|
|||
i18n.ts.enableAll
|
||||
}}</MkButton>
|
||||
<MkSwitch
|
||||
v-for="kind in initialPermissions || kinds"
|
||||
v-for="kind in initialPermissions ?? kinds"
|
||||
:key="kind"
|
||||
v-model="permissions[kind]"
|
||||
style="margin-bottom: 6px"
|
||||
|
|
|
@ -242,7 +242,7 @@ const dialog = ref<InstanceType<typeof XModalWindow>>();
|
|||
|
||||
const tutorial = computed({
|
||||
get() {
|
||||
return defaultStore.reactiveState.tutorial.value || 0;
|
||||
return defaultStore.reactiveState.tutorial.value ?? 0;
|
||||
},
|
||||
set(value) {
|
||||
defaultStore.set("tutorial", value);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
:target="target"
|
||||
:title="url"
|
||||
:class="{
|
||||
hasButton: tweetId || player.url,
|
||||
hasButton: tweetId ?? player.url,
|
||||
}"
|
||||
>
|
||||
<div v-if="thumbnail" class="thumbnail">
|
||||
|
@ -51,10 +51,10 @@
|
|||
<MkLoading mini />
|
||||
</div>
|
||||
<div v-else>
|
||||
<h3 :title="title || undefined">{{ title || url }}</h3>
|
||||
<p :title="description">
|
||||
<h3 :title="title ?? undefined">{{ title ?? url }}</h3>
|
||||
<p :title="description ?? undefined">
|
||||
<span>
|
||||
<span :title="sitename || undefined">
|
||||
<span :title="sitename ?? undefined">
|
||||
<img v-if="icon" class="icon" :src="icon" />
|
||||
{{ sitename }}
|
||||
</span>
|
||||
|
@ -72,7 +72,7 @@
|
|||
: '?autoplay=1&auto_play=1')
|
||||
"
|
||||
:style="`aspect-ratio: ${
|
||||
(player.width || 1) / (player.height || 1)
|
||||
(player.width ?? 1) / (player.height ?? 1)
|
||||
}`"
|
||||
frameborder="0"
|
||||
allow="autoplay; encrypted-media"
|
||||
|
@ -153,7 +153,7 @@ if (
|
|||
requestUrl.hostname = "www.youtube.com";
|
||||
}
|
||||
|
||||
const requestLang = (lang || "ja-JP").replace("ja-KS", "ja-JP");
|
||||
const requestLang = (lang ?? "ja-JP").replace("ja-KS", "ja-JP");
|
||||
|
||||
requestUrl.hash = "";
|
||||
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
<span
|
||||
v-if="user.host || detail || defaultStore.state.showFullAcct"
|
||||
class="host"
|
||||
>@{{ user.host || host }}</span
|
||||
>@{{ user.host ?? host }}</span
|
||||
>
|
||||
</span>
|
||||
</template>
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
<Mfm
|
||||
v-if="show"
|
||||
:class="$style.root"
|
||||
:text="user.name || user.username"
|
||||
:text="user.name ?? user.username"
|
||||
:plain="true"
|
||||
:nowrap="nowrap"
|
||||
:custom-emojis="user.emojis"
|
||||
|
|
|
@ -113,31 +113,31 @@ export default defineComponent({
|
|||
let style: string;
|
||||
switch (token.props.name) {
|
||||
case "tada": {
|
||||
const speed = validTime(token.props.args.speed) || "1s";
|
||||
const delay = validTime(token.props.args.delay) || "0s";
|
||||
const loop = validNumber(token.props.args.loop) || "infinite";
|
||||
// const ease = validEase(token.props.args.ease) || "linear";
|
||||
const speed = validTime(token.props.args.speed) ?? "1s";
|
||||
const delay = validTime(token.props.args.delay) ?? "0s";
|
||||
const loop = validNumber(token.props.args.loop) ?? "infinite";
|
||||
// const ease = validEase(token.props.args.ease) ?? "linear";
|
||||
style = `font-size: 150%; animation: tada ${speed} ${delay} linear ${loop} both;`;
|
||||
break;
|
||||
}
|
||||
case "jelly": {
|
||||
const speed = validTime(token.props.args.speed) || "1s";
|
||||
const delay = validTime(token.props.args.delay) || "0s";
|
||||
const loop = validNumber(token.props.args.loop) || "infinite";
|
||||
const speed = validTime(token.props.args.speed) ?? "1s";
|
||||
const delay = validTime(token.props.args.delay) ?? "0s";
|
||||
const loop = validNumber(token.props.args.loop) ?? "infinite";
|
||||
style = `animation: mfm-rubberBand ${speed} ${delay} linear ${loop} both;`;
|
||||
break;
|
||||
}
|
||||
case "twitch": {
|
||||
const speed = validTime(token.props.args.speed) || "0.5s";
|
||||
const delay = validTime(token.props.args.delay) || "0s";
|
||||
const loop = validNumber(token.props.args.loop) || "infinite";
|
||||
const speed = validTime(token.props.args.speed) ?? "0.5s";
|
||||
const delay = validTime(token.props.args.delay) ?? "0s";
|
||||
const loop = validNumber(token.props.args.loop) ?? "infinite";
|
||||
style = `animation: mfm-twitch ${speed} ${delay} ease ${loop};`;
|
||||
break;
|
||||
}
|
||||
case "shake": {
|
||||
const speed = validTime(token.props.args.speed) || "0.5s";
|
||||
const delay = validTime(token.props.args.delay) || "0s";
|
||||
const loop = validNumber(token.props.args.loop) || "infinite";
|
||||
const speed = validTime(token.props.args.speed) ?? "0.5s";
|
||||
const delay = validTime(token.props.args.delay) ?? "0s";
|
||||
const loop = validNumber(token.props.args.loop) ?? "infinite";
|
||||
style = `animation: mfm-shake ${speed} ${delay} ease ${loop};`;
|
||||
break;
|
||||
}
|
||||
|
@ -152,30 +152,30 @@ export default defineComponent({
|
|||
: token.props.args.y
|
||||
? "mfm-spinY"
|
||||
: "mfm-spin";
|
||||
const speed = validTime(token.props.args.speed) || "1.5s";
|
||||
const delay = validTime(token.props.args.delay) || "0s";
|
||||
const loop = validNumber(token.props.args.loop) || "infinite";
|
||||
const speed = validTime(token.props.args.speed) ?? "1.5s";
|
||||
const delay = validTime(token.props.args.delay) ?? "0s";
|
||||
const loop = validNumber(token.props.args.loop) ?? "infinite";
|
||||
style = `animation: ${anime} ${speed} ${delay} linear ${loop}; animation-direction: ${direction};`;
|
||||
break;
|
||||
}
|
||||
case "jump": {
|
||||
const speed = validTime(token.props.args.speed) || "0.75s";
|
||||
const delay = validTime(token.props.args.delay) || "0s";
|
||||
const loop = validNumber(token.props.args.loop) || "infinite";
|
||||
const speed = validTime(token.props.args.speed) ?? "0.75s";
|
||||
const delay = validTime(token.props.args.delay) ?? "0s";
|
||||
const loop = validNumber(token.props.args.loop) ?? "infinite";
|
||||
style = `animation: mfm-jump ${speed} ${delay} linear ${loop};`;
|
||||
break;
|
||||
}
|
||||
case "bounce": {
|
||||
const speed = validTime(token.props.args.speed) || "0.75s";
|
||||
const delay = validTime(token.props.args.delay) || "0s";
|
||||
const loop = validNumber(token.props.args.loop) || "infinite";
|
||||
const speed = validTime(token.props.args.speed) ?? "0.75s";
|
||||
const delay = validTime(token.props.args.delay) ?? "0s";
|
||||
const loop = validNumber(token.props.args.loop) ?? "infinite";
|
||||
style = `animation: mfm-bounce ${speed} ${delay} linear ${loop}; transform-origin: center bottom;`;
|
||||
break;
|
||||
}
|
||||
case "rainbow": {
|
||||
const speed = validTime(token.props.args.speed) || "1s";
|
||||
const delay = validTime(token.props.args.delay) || "0s";
|
||||
const loop = validNumber(token.props.args.loop) || "infinite";
|
||||
const speed = validTime(token.props.args.speed) ?? "1s";
|
||||
const delay = validTime(token.props.args.delay) ?? "0s";
|
||||
const loop = validNumber(token.props.args.loop) ?? "infinite";
|
||||
style = `animation: mfm-rainbow ${speed} ${delay} linear ${loop};`;
|
||||
break;
|
||||
}
|
||||
|
@ -189,9 +189,9 @@ export default defineComponent({
|
|||
const direction = token.props.args.out
|
||||
? "alternate-reverse"
|
||||
: "alternate";
|
||||
const speed = validTime(token.props.args.speed) || "1.5s";
|
||||
const delay = validTime(token.props.args.delay) || "0s";
|
||||
const loop = validNumber(token.props.args.loop) || "infinite";
|
||||
const speed = validTime(token.props.args.speed) ?? "1.5s";
|
||||
const delay = validTime(token.props.args.delay) ?? "0s";
|
||||
const loop = validNumber(token.props.args.loop) ?? "infinite";
|
||||
style = `animation: mfm-fade ${speed} ${delay} linear ${loop}; animation-direction: ${direction};`;
|
||||
break;
|
||||
}
|
||||
|
@ -395,7 +395,7 @@ export default defineComponent({
|
|||
this.author &&
|
||||
this.author.host != null
|
||||
? this.author.host
|
||||
: token.props.host) || host,
|
||||
: token.props.host) ?? host,
|
||||
username: token.props.username,
|
||||
}),
|
||||
];
|
||||
|
|
|
@ -35,7 +35,7 @@ export default defineComponent({
|
|||
function click() {
|
||||
props.hpml.updatePageVar(
|
||||
props.block.name,
|
||||
value.value + (props.block.inc || 1),
|
||||
value.value + (props.block.inc ?? 1),
|
||||
);
|
||||
props.hpml.eval();
|
||||
}
|
||||
|
|
|
@ -58,7 +58,7 @@ function calc(el: Element) {
|
|||
const info = mountings.get(el);
|
||||
const width = el.clientWidth;
|
||||
|
||||
if (!info || info.previousWidth === width) return;
|
||||
if (info == null || info.previousWidth === width) return;
|
||||
|
||||
// アクティベート前などでsrcが描画されていない場合
|
||||
if (!width) {
|
||||
|
|
|
@ -7,7 +7,7 @@ export const acct = (user: firefish.Acct) => {
|
|||
};
|
||||
|
||||
export const userName = (user: firefish.entities.User) => {
|
||||
return user.name || user.username;
|
||||
return user.name ?? user.username;
|
||||
};
|
||||
|
||||
export const userPage = (user: firefish.Acct, path?, absolute = false) => {
|
||||
|
|
|
@ -123,7 +123,7 @@ function checkForSplash() {
|
|||
|
||||
// #region Set lang attr
|
||||
const html = document.documentElement;
|
||||
html.setAttribute("lang", lang || "en-US");
|
||||
html.setAttribute("lang", lang ?? "en-US");
|
||||
html.setAttribute("dir", langmap[lang].rtl === true ? "rtl" : "ltr");
|
||||
//#endregion
|
||||
|
||||
|
@ -134,7 +134,7 @@ function checkForSplash() {
|
|||
if (loginId) {
|
||||
const target = getUrlWithoutLoginId(location.href);
|
||||
|
||||
if (!$i || $i.id !== loginId) {
|
||||
if ($i == null || $i.id !== loginId) {
|
||||
const account = await getAccountFromId(loginId);
|
||||
if (account) {
|
||||
await login(account.token, target);
|
||||
|
@ -437,7 +437,7 @@ function checkForSplash() {
|
|||
if (Date.now() - lastUsedDate > 1000 * 60 * 60 * 2) {
|
||||
toast(
|
||||
i18n.t("welcomeBackWithName", {
|
||||
name: $i.name || $i.username,
|
||||
name: $i.name ?? $i.username,
|
||||
}),
|
||||
);
|
||||
}
|
||||
|
|
|
@ -314,7 +314,7 @@ export function confirm(props: {
|
|||
},
|
||||
{
|
||||
done: (result) => {
|
||||
resolve(result || { canceled: true });
|
||||
resolve(result ?? { canceled: true });
|
||||
},
|
||||
},
|
||||
"closed",
|
||||
|
@ -342,7 +342,7 @@ export function yesno(props: {
|
|||
},
|
||||
{
|
||||
done: (result) => {
|
||||
resolve(result || { canceled: true });
|
||||
resolve(result ?? { canceled: true });
|
||||
},
|
||||
},
|
||||
"closed",
|
||||
|
@ -383,7 +383,7 @@ export function inputText(props: {
|
|||
},
|
||||
{
|
||||
done: (result) => {
|
||||
resolve(result || { canceled: true });
|
||||
resolve(result ?? { canceled: true });
|
||||
},
|
||||
},
|
||||
"closed",
|
||||
|
@ -421,7 +421,7 @@ export function inputParagraph(props: {
|
|||
},
|
||||
{
|
||||
done: (result) => {
|
||||
resolve(result || { canceled: true });
|
||||
resolve(result ?? { canceled: true });
|
||||
},
|
||||
},
|
||||
"closed",
|
||||
|
@ -461,7 +461,7 @@ export function inputNumber(props: {
|
|||
},
|
||||
{
|
||||
done: (result) => {
|
||||
resolve(result || { canceled: true });
|
||||
resolve(result ?? { canceled: true });
|
||||
},
|
||||
},
|
||||
"closed",
|
||||
|
@ -553,7 +553,7 @@ export function select<C = any>(
|
|||
},
|
||||
{
|
||||
done: (result) => {
|
||||
resolve(result || { canceled: true });
|
||||
resolve(result ?? { canceled: true });
|
||||
},
|
||||
},
|
||||
"closed",
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
:key="category"
|
||||
class="emojis"
|
||||
>
|
||||
<template #header>{{ category || i18n.ts.other }}</template>
|
||||
<template #header>{{ category ?? i18n.ts.other }}</template>
|
||||
<div class="zuvgdzyt">
|
||||
<XEmoji
|
||||
v-for="emoji in customEmojis.filter(
|
||||
|
|
|
@ -41,7 +41,7 @@
|
|||
@click="easterEgg"
|
||||
/>
|
||||
<div class="name">
|
||||
<b>{{ $instance.name || host }}</b>
|
||||
<b>{{ $instance.name ?? host }}</b>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
@ -99,7 +99,7 @@
|
|||
></template>
|
||||
{{
|
||||
i18n.t("_aboutFirefish.donateHost", {
|
||||
host: $instance.name || host,
|
||||
host: $instance.name ?? host,
|
||||
})
|
||||
}}
|
||||
<template #suffix>Donate</template>
|
||||
|
@ -209,7 +209,7 @@ withDefaults(
|
|||
const stats = ref(null);
|
||||
const instanceIcon = ref<HTMLImageElement>();
|
||||
let iconClicks = 0;
|
||||
const iconSrc = ref(instance.iconUrl || instance.faviconUrl || "/favicon.ico");
|
||||
const iconSrc = ref(instance.faviconUrl ?? instance.iconUrl ?? "/favicon.ico");
|
||||
const instanceIconAnimation = ref("");
|
||||
const tabs = ["overview", "emojis", "charts"];
|
||||
const tab = ref(tabs[0]);
|
||||
|
@ -276,8 +276,8 @@ function easterEgg() {
|
|||
setTimeout(() => {
|
||||
if (iconClicks % 6 === 0) {
|
||||
iconSrc.value =
|
||||
instance.iconUrl ||
|
||||
instance.faviconUrl ||
|
||||
instance.faviconUrl ??
|
||||
instance.iconUrl ??
|
||||
"/favicon.ico";
|
||||
} else {
|
||||
iconSrc.value = "/static-assets/woozy.png";
|
||||
|
|
|
@ -148,7 +148,7 @@ function onTabClick(tab: Tab, ev: MouseEvent): void {
|
|||
}
|
||||
|
||||
const calcBg = () => {
|
||||
const rawBg = metadata?.bg || "var(--bg)";
|
||||
const rawBg = metadata?.bg ?? "var(--bg)";
|
||||
const tinyBg = tinycolor(
|
||||
rawBg.startsWith("var(")
|
||||
? getComputedStyle(document.documentElement).getPropertyValue(
|
||||
|
|
|
@ -32,7 +32,7 @@
|
|||
<MkCaptcha
|
||||
provider="hcaptcha"
|
||||
:sitekey="
|
||||
hcaptchaSiteKey ||
|
||||
hcaptchaSiteKey ??
|
||||
'10000000-ffff-ffff-ffff-000000000001'
|
||||
"
|
||||
/>
|
||||
|
|
|
@ -47,7 +47,7 @@ async function init() {
|
|||
function save() {
|
||||
os.apiWithDialog("admin/update-meta", {
|
||||
hiddenTags:
|
||||
hiddenTags.value.split("\n").map((h: string) => h.trim()) || [],
|
||||
hiddenTags.value.split("\n").map((h: string) => h.trim()) ?? [],
|
||||
}).then(() => {
|
||||
fetchInstance();
|
||||
});
|
||||
|
|
|
@ -5,7 +5,11 @@
|
|||
<div class="lxpfedzu">
|
||||
<div class="banner">
|
||||
<img
|
||||
:src="$instance.iconUrl || '/favicon.ico'"
|
||||
:src="
|
||||
$instance.faviconUrl ??
|
||||
$instance.iconUrl ??
|
||||
'/favicon.ico'
|
||||
"
|
||||
alt=""
|
||||
class="icon"
|
||||
/>
|
||||
|
|
|
@ -69,9 +69,9 @@ async function init() {
|
|||
|
||||
function save() {
|
||||
os.apiWithDialog("admin/update-meta", {
|
||||
blockedHosts: blockedHosts.value.split("\n").map((h) => h.trim()) || [],
|
||||
blockedHosts: blockedHosts.value.split("\n").map((h) => h.trim()) ?? [],
|
||||
silencedHosts:
|
||||
silencedHosts.value.split("\n").map((h) => h.trim()) || [],
|
||||
silencedHosts.value.split("\n").map((h) => h.trim()) ?? [],
|
||||
}).then(() => {
|
||||
fetchInstance();
|
||||
});
|
||||
|
|
|
@ -66,7 +66,7 @@ async function addRelay() {
|
|||
.catch((err: any) => {
|
||||
os.alert({
|
||||
type: "error",
|
||||
text: err.message || err,
|
||||
text: err.message ?? err,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
@ -81,7 +81,7 @@ function remove(inbox: string) {
|
|||
.catch((err: any) => {
|
||||
os.alert({
|
||||
type: "error",
|
||||
text: err.message || err,
|
||||
text: err.message ?? err,
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
|
@ -126,7 +126,7 @@ const accepted = () => {
|
|||
} else {
|
||||
location.href = `${session.value.app.callbackUrl}?token=${
|
||||
session.value.token
|
||||
}&code=${session.value.token}&state=${getUrlParams().state || ""}`;
|
||||
}&code=${session.value.token}&state=${getUrlParams().state ?? ""}`;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
|
|
@ -41,7 +41,7 @@ function menu(ev) {
|
|||
(res) => {
|
||||
os.alert({
|
||||
type: "info",
|
||||
text: `${res.license || i18n.ts.notSet}`,
|
||||
text: `${res.license ?? i18n.ts.notSet}`,
|
||||
});
|
||||
},
|
||||
);
|
||||
|
|
|
@ -11,7 +11,7 @@ import { i18n } from "@/i18n";
|
|||
async function follow(user): Promise<void> {
|
||||
const { canceled } = await os.confirm({
|
||||
type: "question",
|
||||
text: i18n.t("followConfirm", { name: user.name || user.username }),
|
||||
text: i18n.t("followConfirm", { name: user.name ?? user.username }),
|
||||
});
|
||||
|
||||
if (canceled) {
|
||||
|
|
|
@ -105,7 +105,7 @@
|
|||
<MkAcct :user="post.user" />
|
||||
</div>
|
||||
<MkFollowButton
|
||||
v-if="!$i || $i.id != post.user.id"
|
||||
v-if="!isSignedIn || $i.id !== post.user.id"
|
||||
:user="post.user"
|
||||
:inline="true"
|
||||
:transparent="false"
|
||||
|
@ -163,7 +163,7 @@ import { definePageMetadata } from "@/scripts/page-metadata";
|
|||
import { shareAvailable } from "@/scripts/share-available";
|
||||
import { defaultStore } from "@/store";
|
||||
import icon from "@/scripts/icon";
|
||||
import { isSignedIn } from "@/reactiveAccount";
|
||||
import { $i, isSignedIn } from "@/reactiveAccount";
|
||||
|
||||
const router = useRouter();
|
||||
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
<div class="fnfelxur">
|
||||
<img :src="faviconUrl" alt="" class="icon" />
|
||||
<span class="name">{{
|
||||
instance.name || `(${i18n.ts.unknown})`
|
||||
instance.name ?? `(${i18n.ts.unknown})`
|
||||
}}</span>
|
||||
</div>
|
||||
<MkKeyValue :copy="host" oneline style="margin: 1em 0">
|
||||
|
@ -51,12 +51,12 @@
|
|||
<template #value
|
||||
><span class="_monospace"
|
||||
>{{
|
||||
instance.softwareName ||
|
||||
instance.softwareName ??
|
||||
`(${i18n.ts.unknown})`
|
||||
}}
|
||||
/
|
||||
{{
|
||||
instance.softwareVersion ||
|
||||
instance.softwareVersion ??
|
||||
`(${i18n.ts.unknown})`
|
||||
}}</span
|
||||
></template
|
||||
|
@ -68,11 +68,11 @@
|
|||
}}</template>
|
||||
<template #value
|
||||
>{{
|
||||
instance.maintainerName ||
|
||||
instance.maintainerName ??
|
||||
`(${i18n.ts.unknown})`
|
||||
}}
|
||||
({{
|
||||
instance.maintainerEmail ||
|
||||
instance.maintainerEmail ??
|
||||
`(${i18n.ts.unknown})`
|
||||
}})</template
|
||||
>
|
||||
|
|
|
@ -238,7 +238,7 @@ function clear() {
|
|||
}
|
||||
|
||||
function saveDraft() {
|
||||
const drafts = JSON.parse(localStorage.getItem("message_drafts") || "{}");
|
||||
const drafts = JSON.parse(localStorage.getItem("message_drafts") ?? "{}");
|
||||
|
||||
drafts[draftKey.value] = {
|
||||
updatedAt: new Date(),
|
||||
|
@ -252,7 +252,7 @@ function saveDraft() {
|
|||
}
|
||||
|
||||
function deleteDraft() {
|
||||
const drafts = JSON.parse(localStorage.getItem("message_drafts") || "{}");
|
||||
const drafts = JSON.parse(localStorage.getItem("message_drafts") ?? "{}");
|
||||
|
||||
delete drafts[draftKey.value];
|
||||
|
||||
|
@ -270,7 +270,7 @@ onMounted(() => {
|
|||
new Autocomplete(textEl.value, text);
|
||||
|
||||
// 書きかけの投稿を復元
|
||||
const draft = JSON.parse(localStorage.getItem("message_drafts") || "{}")[
|
||||
const draft = JSON.parse(localStorage.getItem("message_drafts") ?? "{}")[
|
||||
draftKey.value
|
||||
];
|
||||
if (draft) {
|
||||
|
|
|
@ -11,7 +11,7 @@
|
|||
<MkPagination
|
||||
v-if="pagination"
|
||||
ref="pagingComponent"
|
||||
:key="userAcct || groupId"
|
||||
:key="userAcct ?? groupId"
|
||||
:pagination="pagination"
|
||||
>
|
||||
<template #empty>
|
||||
|
@ -162,7 +162,7 @@ async function fetch() {
|
|||
const acct = Acct.parse(props.userAcct);
|
||||
user.value = await os.api("users/show", {
|
||||
username: acct.username,
|
||||
host: acct.host || undefined,
|
||||
host: acct.host ?? undefined,
|
||||
});
|
||||
group.value = null;
|
||||
|
||||
|
|
|
@ -181,7 +181,7 @@ definePageMetadata(
|
|||
? ""
|
||||
: i18n.t("noteOf", {
|
||||
user:
|
||||
appearNote.value.user.name ||
|
||||
appearNote.value.user.name ??
|
||||
appearNote.value.user.username,
|
||||
}),
|
||||
subtitle: new Date(
|
||||
|
@ -192,7 +192,7 @@ definePageMetadata(
|
|||
share: {
|
||||
title: i18n.t("noteOf", {
|
||||
user:
|
||||
appearNote.value.user.name ||
|
||||
appearNote.value.user.name ??
|
||||
appearNote.value.user.username,
|
||||
}),
|
||||
text: appearNote.value.text,
|
||||
|
|
|
@ -150,7 +150,7 @@
|
|||
<MkAcct :user="page.user" />
|
||||
</div>
|
||||
<MkFollowButton
|
||||
v-if="!$i || $i.id != page.user.id"
|
||||
v-if="!isSignedIn || $i.id !== page.user.id"
|
||||
:user="page.user"
|
||||
:inline="true"
|
||||
:transparent="false"
|
||||
|
@ -215,7 +215,7 @@ import { definePageMetadata } from "@/scripts/page-metadata";
|
|||
import { shareAvailable } from "@/scripts/share-available";
|
||||
import { defaultStore } from "@/store";
|
||||
import icon from "@/scripts/icon";
|
||||
import { isSignedIn } from "@/reactiveAccount";
|
||||
import { $i, isSignedIn } from "@/reactiveAccount";
|
||||
|
||||
const props = defineProps<{
|
||||
pageName: string;
|
||||
|
@ -272,7 +272,7 @@ function share() {
|
|||
|
||||
function shareWithNote() {
|
||||
os.post({
|
||||
initialText: `${page.value.title || page.value.name} ${url}/@${
|
||||
initialText: `${page.value.title ?? page.value.name} ${url}/@${
|
||||
page.value.user.username
|
||||
}/pages/${page.value.name}`,
|
||||
});
|
||||
|
@ -312,11 +312,11 @@ definePageMetadata(
|
|||
computed(() =>
|
||||
page.value
|
||||
? {
|
||||
title: computed(() => page.value.title || page.value.name),
|
||||
title: computed(() => page.value.title ?? page.value.name),
|
||||
avatar: page.value.user,
|
||||
path: `/@${page.value.user.username}/pages/${page.value.name}`,
|
||||
share: {
|
||||
title: page.value.title || page.value.name,
|
||||
title: page.value.title ?? page.value.name,
|
||||
text: page.value.summary,
|
||||
},
|
||||
}
|
||||
|
|
|
@ -66,7 +66,7 @@ const pushRegistrationInServer = computed(
|
|||
() => allowButton.value?.pushRegistrationInServer,
|
||||
);
|
||||
const sendReadMessage = computed(
|
||||
() => pushRegistrationInServer.value?.sendReadMessage || false,
|
||||
() => pushRegistrationInServer.value?.sendReadMessage ?? false,
|
||||
);
|
||||
|
||||
async function readAllUnreadNotes() {
|
||||
|
|
|
@ -169,7 +169,7 @@ const connection = isSignedIn && stream.useChannel("main");
|
|||
const profiles = ref<Record<string, Profile> | null>(null);
|
||||
|
||||
os.api("i/registry/get-all", { scope }).then((res) => {
|
||||
profiles.value = res || {};
|
||||
profiles.value = res ?? {};
|
||||
});
|
||||
|
||||
function isObject(value: unknown): value is Record<string, unknown> {
|
||||
|
|
|
@ -21,7 +21,7 @@
|
|||
>
|
||||
{{ i18n.t("_sfx." + type) }}
|
||||
<template #suffix>{{
|
||||
sounds[type].type || i18n.ts.none
|
||||
sounds[type].type ?? i18n.ts.none
|
||||
}}</template>
|
||||
<template #suffixIcon
|
||||
><i :class="icon('ph-caret-down')"></i
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
:style="{ color: 'var(--error)' }"
|
||||
></i>
|
||||
</template>
|
||||
{{ webhook.name || webhook.url }}
|
||||
{{ webhook.name ?? webhook.url }}
|
||||
<template #suffix>
|
||||
<MkTime
|
||||
v-if="webhook.latestSentAt"
|
||||
|
|
|
@ -108,7 +108,7 @@
|
|||
v-if="
|
||||
patrons?.includes(
|
||||
`@${user.username}@${
|
||||
user.host || host
|
||||
user.host ?? host
|
||||
}`,
|
||||
)
|
||||
"
|
||||
|
@ -197,7 +197,7 @@
|
|||
v-if="
|
||||
patrons?.includes(
|
||||
`@${user.username}@${
|
||||
user.host || host
|
||||
user.host ?? host
|
||||
}`,
|
||||
)
|
||||
"
|
||||
|
|
|
@ -17,8 +17,8 @@
|
|||
<div class="main">
|
||||
<img
|
||||
:src="
|
||||
instance.iconUrl ||
|
||||
instance.faviconUrl ||
|
||||
instance.faviconUrl ??
|
||||
instance.iconUrl ??
|
||||
'/favicon.ico'
|
||||
"
|
||||
alt=""
|
||||
|
@ -41,7 +41,7 @@
|
|||
<div
|
||||
class="desc"
|
||||
v-html="
|
||||
meta.description || i18n.ts.headlineFirefish
|
||||
meta.description ?? i18n.ts.headlineFirefish
|
||||
"
|
||||
></div>
|
||||
</div>
|
||||
|
|
|
@ -15,7 +15,7 @@
|
|||
<div class="about">
|
||||
<div
|
||||
class="desc"
|
||||
v-html="meta.description || i18n.ts.headlineFirefish"
|
||||
v-html="meta.description ?? i18n.ts.headlineFirefish"
|
||||
></div>
|
||||
</div>
|
||||
<div class="action">
|
||||
|
|
|
@ -30,7 +30,7 @@
|
|||
<div
|
||||
class="desc"
|
||||
v-html="
|
||||
meta.description || i18n.ts.headlineFirefish
|
||||
meta.description ?? i18n.ts.headlineFirefish
|
||||
"
|
||||
></div>
|
||||
</div>
|
||||
|
|
|
@ -41,16 +41,16 @@ export class Storage<T extends StateDef> {
|
|||
|
||||
// TODO: indexedDBにする
|
||||
const deviceState = JSON.parse(
|
||||
localStorage.getItem(this.keyForLocalStorage) || "{}",
|
||||
localStorage.getItem(this.keyForLocalStorage) ?? "{}",
|
||||
);
|
||||
const deviceAccountState = isSignedIn
|
||||
? JSON.parse(
|
||||
localStorage.getItem(`${this.keyForLocalStorage}::${$i.id}`) || "{}",
|
||||
localStorage.getItem(`${this.keyForLocalStorage}::${$i.id}`) ?? "{}",
|
||||
)
|
||||
: {};
|
||||
const registryCache = isSignedIn
|
||||
? JSON.parse(
|
||||
localStorage.getItem(`${this.keyForLocalStorage}::cache::${$i.id}`) ||
|
||||
localStorage.getItem(`${this.keyForLocalStorage}::cache::${$i.id}`) ??
|
||||
"{}",
|
||||
)
|
||||
: {};
|
||||
|
@ -136,7 +136,7 @@ export class Storage<T extends StateDef> {
|
|||
const cache = JSON.parse(
|
||||
localStorage.getItem(
|
||||
`${this.keyForLocalStorage}::cache::${$i.id}`,
|
||||
) || "{}",
|
||||
) ?? "{}",
|
||||
);
|
||||
if (cache[key] !== value) {
|
||||
cache[key] = value;
|
||||
|
@ -159,7 +159,7 @@ export class Storage<T extends StateDef> {
|
|||
switch (this.def[key].where) {
|
||||
case "device": {
|
||||
const deviceState = JSON.parse(
|
||||
localStorage.getItem(this.keyForLocalStorage) || "{}",
|
||||
localStorage.getItem(this.keyForLocalStorage) ?? "{}",
|
||||
);
|
||||
deviceState[key] = value;
|
||||
localStorage.setItem(
|
||||
|
@ -171,7 +171,7 @@ export class Storage<T extends StateDef> {
|
|||
case "deviceAccount": {
|
||||
if (!isSignedIn) break;
|
||||
const deviceAccountState = JSON.parse(
|
||||
localStorage.getItem(`${this.keyForLocalStorage}::${$i.id}`) || "{}",
|
||||
localStorage.getItem(`${this.keyForLocalStorage}::${$i.id}`) ?? "{}",
|
||||
);
|
||||
deviceAccountState[key] = value;
|
||||
localStorage.setItem(
|
||||
|
@ -183,7 +183,7 @@ export class Storage<T extends StateDef> {
|
|||
case "account": {
|
||||
if (!isSignedIn) break;
|
||||
const cache = JSON.parse(
|
||||
localStorage.getItem(`${this.keyForLocalStorage}::cache::${$i.id}`) ||
|
||||
localStorage.getItem(`${this.keyForLocalStorage}::cache::${$i.id}`) ??
|
||||
"{}",
|
||||
);
|
||||
cache[key] = value;
|
||||
|
|
|
@ -143,7 +143,7 @@ function registerPostFormAction({ pluginId, title, handler }) {
|
|||
pluginContext.execFn(handler, [
|
||||
utils.jsToVal(form),
|
||||
values.FN_NATIVE(([key, value]) => {
|
||||
if (!key || !value) {
|
||||
if (key == null || value == null) {
|
||||
return;
|
||||
}
|
||||
update(utils.valToJs(key), utils.valToJs(value));
|
||||
|
|
|
@ -9,6 +9,6 @@ export const $i = accountData
|
|||
: null;
|
||||
|
||||
export const isSignedIn = $i != null;
|
||||
export const isModerator = isSignedIn && ($i.isModerator || $i.isAdmin);
|
||||
export const isAdmin = isSignedIn && $i.isAdmin;
|
||||
export const isEmojiMod = isSignedIn && $i.emojiModPerm !== "unauthorized";
|
||||
export const isModerator = $i != null && ($i.isModerator || $i.isAdmin);
|
||||
export const isAdmin = $i?.isAdmin;
|
||||
export const isEmojiMod = $i != null && $i?.emojiModPerm !== "unauthorized";
|
||||
|
|
|
@ -34,7 +34,7 @@ export function createAiScriptEnv(opts) {
|
|||
const res = await os.api(
|
||||
ep.value,
|
||||
utils.valToJs(param),
|
||||
token ? token.value : opts.token || null,
|
||||
token ? token.value : opts.token ?? null,
|
||||
);
|
||||
return utils.jsToVal(res);
|
||||
}),
|
||||
|
|
|
@ -15,7 +15,7 @@ function checkLangMute(
|
|||
const mutedLangList = new Set(mutedLangs.flatMap((e) => e));
|
||||
// handle subtags
|
||||
// e.g. if lang = "zh-hant-tw", check ["zh", "zh-hant", "zh-hant-tw"]
|
||||
const langChunks: string[] = (note.lang || "").split("-");
|
||||
const langChunks: string[] = (note.lang ?? "").split("-");
|
||||
for (let i = 0; i < langChunks.length; i++) {
|
||||
const lang = langChunks.slice(0, i + 1).join("-");
|
||||
if (mutedLangList.has(lang)) {
|
||||
|
|
|
@ -12,7 +12,7 @@ ChiptuneJsConfig.prototype.constructor = ChiptuneJsConfig;
|
|||
export function ChiptuneJsPlayer(config: object) {
|
||||
this.libopenmpt = null;
|
||||
this.config = config;
|
||||
this.audioContext = config.context || new ChiptuneAudioContext();
|
||||
this.audioContext = config.context ?? new ChiptuneAudioContext();
|
||||
this.context = this.audioContext.createGain();
|
||||
this.currentPlayingNode = null;
|
||||
this.handlers = [];
|
||||
|
@ -157,7 +157,7 @@ ChiptuneJsPlayer.prototype.play = async function (buffer: ArrayBuffer) {
|
|||
}
|
||||
this.libopenmpt._openmpt_module_set_repeat_count(
|
||||
processNode.modulePtr,
|
||||
this.config.repeatCount || 0,
|
||||
this.config.repeatCount ?? 0,
|
||||
);
|
||||
this.currentPlayingNode = processNode;
|
||||
processNode.connect(this.context);
|
||||
|
|
|
@ -6,19 +6,19 @@ export function collectPageVars(content) {
|
|||
pageVars.push({
|
||||
name: x.name,
|
||||
type: "string",
|
||||
value: x.default || "",
|
||||
value: x.default ?? "",
|
||||
});
|
||||
} else if (x.type === "textareaInput") {
|
||||
pageVars.push({
|
||||
name: x.name,
|
||||
type: "string",
|
||||
value: x.default || "",
|
||||
value: x.default ?? "",
|
||||
});
|
||||
} else if (x.type === "numberInput") {
|
||||
pageVars.push({
|
||||
name: x.name,
|
||||
type: "number",
|
||||
value: x.default || 0,
|
||||
value: x.default ?? 0,
|
||||
});
|
||||
} else if (x.type === "switch") {
|
||||
pageVars.push({
|
||||
|
@ -36,7 +36,7 @@ export function collectPageVars(content) {
|
|||
pageVars.push({
|
||||
name: x.name,
|
||||
type: "string",
|
||||
value: x.default || "",
|
||||
value: x.default ?? "",
|
||||
});
|
||||
} else if (x.children) {
|
||||
collect(x.children);
|
||||
|
|
|
@ -37,7 +37,7 @@ export const categoryMapping = {
|
|||
} as const;
|
||||
|
||||
export function addSkinTone(emoji: string, skinTone?: number) {
|
||||
const chosenSkinTone = skinTone || defaultStore.state.reactionPickerSkinTone;
|
||||
const chosenSkinTone = skinTone ?? defaultStore.state.reactionPickerSkinTone;
|
||||
const skinToneModifiers = [
|
||||
"",
|
||||
emojiComponents.light_skin_tone,
|
||||
|
@ -51,7 +51,7 @@ export function addSkinTone(emoji: string, skinTone?: number) {
|
|||
"",
|
||||
);
|
||||
if (individualData[strippedEmoji].skin_tone_support) {
|
||||
return strippedEmoji + (skinToneModifiers[chosenSkinTone - 1] || "");
|
||||
return strippedEmoji + (skinToneModifiers[chosenSkinTone - 1] ?? "");
|
||||
} else {
|
||||
return emoji;
|
||||
}
|
||||
|
@ -62,7 +62,7 @@ const newData = {};
|
|||
for (const originalCategory of Object.keys(data)) {
|
||||
const newCategory = categoryMapping[originalCategory];
|
||||
if (newCategory) {
|
||||
newData[newCategory] = newData[newCategory] || [];
|
||||
newData[newCategory] = newData[newCategory] ?? [];
|
||||
for (const emojiIndex of Object.keys(data[originalCategory])) {
|
||||
const emojiObj = { ...data[originalCategory][emojiIndex] };
|
||||
emojiObj.category = newCategory;
|
||||
|
@ -79,8 +79,8 @@ export const emojilist: UnicodeEmojiDef[] = Object.keys(newData).reduce(
|
|||
emoji: item.emoji,
|
||||
slug: item.slug,
|
||||
category: item.category,
|
||||
skin_tone_support: item.skin_tone_support || false,
|
||||
keywords: item.keywords || [],
|
||||
skin_tone_support: item.skin_tone_support ?? false,
|
||||
keywords: item.keywords ?? [],
|
||||
};
|
||||
});
|
||||
return acc.concat(categoryItems);
|
||||
|
@ -92,6 +92,6 @@ export function getNicelyLabeledCategory(internalName) {
|
|||
return (
|
||||
Object.keys(categoryMapping).find(
|
||||
(key) => categoryMapping[key] === internalName,
|
||||
) || internalName
|
||||
) ?? internalName
|
||||
);
|
||||
}
|
||||
|
|
|
@ -28,7 +28,7 @@ function formatLocaleString(date: Date, format: string): string {
|
|||
].includes(kind)
|
||||
) {
|
||||
return date.toLocaleString(window.navigator.language, {
|
||||
[kind]: option || defaultLocaleStringFormats[kind],
|
||||
[kind]: option ?? defaultLocaleStringFormats[kind],
|
||||
});
|
||||
} else {
|
||||
return match;
|
||||
|
@ -55,8 +55,14 @@ export function formatDateTimeString(date: Date, format: string): string {
|
|||
.replace(/d/g, date.getDate().toString())
|
||||
.replace(/HH/g, `0${date.getHours()}`.slice(-2))
|
||||
.replace(/H/g, date.getHours().toString())
|
||||
.replace(/hh/g, `0${date.getHours() % 12 || 12}`.slice(-2))
|
||||
.replace(/h/g, (date.getHours() % 12 || 12).toString())
|
||||
.replace(
|
||||
/hh/g,
|
||||
`0${date.getHours() % 12 === 0 ? 12 : date.getHours() % 12}`.slice(-2),
|
||||
)
|
||||
.replace(
|
||||
/h/g,
|
||||
(date.getHours() % 12 === 0 ? 12 : date.getHours() % 12).toString(),
|
||||
)
|
||||
.replace(/mm/g, `0${date.getMinutes()}`.slice(-2))
|
||||
.replace(/m/g, date.getMinutes().toString())
|
||||
.replace(/ss/g, `0${date.getSeconds()}`.slice(-2))
|
||||
|
|
|
@ -266,7 +266,7 @@ export function getNoteMenu(props: {
|
|||
props.translating.value = true;
|
||||
props.translation.value = await translate_(
|
||||
appearNote.id,
|
||||
translateLang || lang || navigator.language,
|
||||
translateLang ?? lang ?? navigator.language,
|
||||
);
|
||||
|
||||
// use UI language as the second translation target
|
||||
|
@ -274,7 +274,7 @@ export function getNoteMenu(props: {
|
|||
translateLang != null &&
|
||||
lang != null &&
|
||||
translateLang !== lang &&
|
||||
(!props.translation.value ||
|
||||
(props.translation.value == null ||
|
||||
props.translation.value.sourceLang.toLowerCase() ===
|
||||
translateLang.slice(0, 2))
|
||||
)
|
||||
|
@ -349,7 +349,7 @@ export function getNoteMenu(props: {
|
|||
},
|
||||
),
|
||||
isAppearAuthor
|
||||
? ($i.pinnedNoteIds || []).includes(appearNote.id)
|
||||
? ($i.pinnedNoteIds ?? []).includes(appearNote.id)
|
||||
? {
|
||||
icon: `${icon("ph-push-pin")}`,
|
||||
text: i18n.ts.unpin,
|
||||
|
@ -368,12 +368,12 @@ export function getNoteMenu(props: {
|
|||
action: translate,
|
||||
}
|
||||
: undefined,
|
||||
appearNote.url || appearNote.uri
|
||||
appearNote.url ?? appearNote.uri
|
||||
? {
|
||||
icon: `${icon("ph-arrow-square-out")}`,
|
||||
text: i18n.ts.showOnRemote,
|
||||
action: () => {
|
||||
window.open(appearNote.url || appearNote.uri, "_blank");
|
||||
window.open(appearNote.url ?? appearNote.uri, "_blank");
|
||||
},
|
||||
}
|
||||
: undefined,
|
||||
|
@ -392,7 +392,7 @@ export function getNoteMenu(props: {
|
|||
text: i18n.ts.copyLink,
|
||||
action: copyLink,
|
||||
},
|
||||
appearNote.url || appearNote.uri
|
||||
appearNote.url ?? appearNote.uri
|
||||
? {
|
||||
icon: `${icon("ph-link-simple")}`,
|
||||
text: `${i18n.ts.copyLink} (${i18n.ts.origin})`,
|
||||
|
@ -425,8 +425,8 @@ export function getNoteMenu(props: {
|
|||
text: i18n.ts.reportAbuse,
|
||||
action: () => {
|
||||
const u =
|
||||
appearNote.url ||
|
||||
appearNote.uri ||
|
||||
appearNote.url ??
|
||||
appearNote.uri ??
|
||||
`${url}/notes/${appearNote.id}`;
|
||||
os.popup(
|
||||
defineAsyncComponent(
|
||||
|
@ -490,12 +490,12 @@ export function getNoteMenu(props: {
|
|||
].filter((x) => x !== undefined);
|
||||
} else {
|
||||
menu = [
|
||||
appearNote.url || appearNote.uri
|
||||
appearNote.url ?? appearNote.uri
|
||||
? {
|
||||
icon: `${icon("ph-arrow-square-out")}`,
|
||||
text: i18n.ts.showOnRemote,
|
||||
action: () => {
|
||||
window.open(appearNote.url || appearNote.uri, "_blank");
|
||||
window.open(appearNote.url ?? appearNote.uri, "_blank");
|
||||
},
|
||||
}
|
||||
: undefined,
|
||||
|
@ -509,7 +509,7 @@ export function getNoteMenu(props: {
|
|||
text: i18n.ts.copyLink,
|
||||
action: copyLink,
|
||||
},
|
||||
appearNote.url || appearNote.uri
|
||||
appearNote.url ?? appearNote.uri
|
||||
? {
|
||||
icon: `${icon("ph-link-simple")}`,
|
||||
text: `${i18n.ts.copyLink} (${i18n.ts.origin})`,
|
||||
|
|
|
@ -21,7 +21,7 @@ export const getNoteSummary = (note: firefish.entities.Note): string => {
|
|||
}
|
||||
|
||||
// ファイルが添付されているとき
|
||||
if ((note.files || []).length !== 0) {
|
||||
if ((note.files ?? []).length !== 0) {
|
||||
const len = note.files?.length;
|
||||
summary += ` 📎${len !== 1 ? ` (${len})` : ""}`;
|
||||
}
|
||||
|
|
|
@ -227,14 +227,14 @@ export function getUserMenu(user, router: Router = mainRouter) {
|
|||
{
|
||||
type: "label",
|
||||
text: user.host
|
||||
? `@${user.username}@${user.host || host}`
|
||||
? `@${user.username}@${user.host ?? host}`
|
||||
: `@${user.username}`,
|
||||
},
|
||||
{
|
||||
icon: `${icon("ph-at")}`,
|
||||
text: i18n.ts.copyUsername,
|
||||
action: () => {
|
||||
copyToClipboard(`@${user.username}@${user.host || host}`);
|
||||
copyToClipboard(`@${user.username}@${user.host ?? host}`);
|
||||
},
|
||||
},
|
||||
{
|
||||
|
|
|
@ -2,5 +2,5 @@ export default function (user: {
|
|||
name?: string | null;
|
||||
username: string;
|
||||
}): string {
|
||||
return user.name || user.username;
|
||||
return user.name ?? user.username;
|
||||
}
|
||||
|
|
|
@ -79,7 +79,7 @@ export class Hpml {
|
|||
? `${opts.url}/@${this.page.user.username}/pages/${this.page.name}`
|
||||
: "",
|
||||
LOGIN: opts.visitor != null,
|
||||
NAME: opts.visitor ? opts.visitor.name || opts.visitor.username : "",
|
||||
NAME: opts.visitor ? opts.visitor.name ?? opts.visitor.username : "",
|
||||
USERNAME: opts.visitor ? opts.visitor.username : "",
|
||||
USERID: opts.visitor ? opts.visitor.id : "",
|
||||
NOTES_COUNT: opts.visitor ? opts.visitor.notesCount : 0,
|
||||
|
@ -187,11 +187,11 @@ export class Hpml {
|
|||
}
|
||||
|
||||
if (expr.type === "text" || expr.type === "multiLineText") {
|
||||
return this._interpolateScope(expr.value || "", scope);
|
||||
return this._interpolateScope(expr.value ?? "", scope);
|
||||
}
|
||||
|
||||
if (expr.type === "textList") {
|
||||
return this._interpolateScope(expr.value || "", scope)
|
||||
return this._interpolateScope(expr.value ?? "", scope)
|
||||
.trim()
|
||||
.split("\n");
|
||||
}
|
||||
|
|
|
@ -103,7 +103,7 @@ export class HpmlScope {
|
|||
name?: HpmlScope["name"],
|
||||
) {
|
||||
this.layerdStates = layerdStates;
|
||||
this.name = name || "anonymous";
|
||||
this.name = name ?? "anonymous";
|
||||
}
|
||||
|
||||
@autobind
|
||||
|
|
|
@ -504,7 +504,7 @@ export function initHpmlLib(
|
|||
strPick: (a: string, b: number) => a[b - 1],
|
||||
strReplace: (a: string, b: string, c: string) => a.split(b).join(c),
|
||||
strReverse: (a: string) => a.split("").reverse().join(""),
|
||||
join: (texts: string[], separator: string) => texts.join(separator || ""),
|
||||
join: (texts: string[], separator: string) => texts.join(separator ?? ""),
|
||||
stringToNumber: (a: string) => parseInt(a),
|
||||
numberToString: (a: number) => a.toString(),
|
||||
splitStrByLine: (a: string) => a.split("\n"),
|
||||
|
|
|
@ -30,7 +30,7 @@ export class HpmlTypeChecker {
|
|||
public typeCheck(v: Expr): TypeError | null {
|
||||
if (isLiteralValue(v)) return null;
|
||||
|
||||
const def = funcDefs[v.type || ""];
|
||||
const def = funcDefs[v.type ?? ""];
|
||||
if (def == null) {
|
||||
throw new Error(`Unknown type: ${v.type}`);
|
||||
}
|
||||
|
@ -66,7 +66,7 @@ export class HpmlTypeChecker {
|
|||
|
||||
@autobind
|
||||
public getExpectedType(v: Expr, slot: number): Type {
|
||||
const def = funcDefs[v.type || ""];
|
||||
const def = funcDefs[v.type ?? ""];
|
||||
if (def == null) {
|
||||
throw new Error(`Unknown type: ${v.type}`);
|
||||
}
|
||||
|
@ -86,7 +86,7 @@ export class HpmlTypeChecker {
|
|||
}
|
||||
|
||||
if (typeof def.in[slot] === "number") {
|
||||
return generic[def.in[slot]] || null;
|
||||
return generic[def.in[slot]] ?? null;
|
||||
} else {
|
||||
return def.in[slot];
|
||||
}
|
||||
|
@ -110,7 +110,7 @@ export class HpmlTypeChecker {
|
|||
return pageVar.type;
|
||||
}
|
||||
|
||||
const envVar = envVarsDef[v.value || ""];
|
||||
const envVar = envVarsDef[v.value ?? ""];
|
||||
if (envVar !== undefined) {
|
||||
return envVar;
|
||||
}
|
||||
|
|
|
@ -90,7 +90,7 @@ export function physics(container: HTMLElement) {
|
|||
objEl.offsetHeight,
|
||||
{
|
||||
chamfer: {
|
||||
radius: parseInt(style.borderRadius || "0", 10),
|
||||
radius: parseInt(style.borderRadius ?? "0", 10),
|
||||
},
|
||||
restitution: 0.5,
|
||||
},
|
||||
|
|
|
@ -36,7 +36,7 @@ export function isBottomVisible(
|
|||
}
|
||||
|
||||
export function onScrollTop(el: Element, cb) {
|
||||
const container = getScrollContainer(el) || window;
|
||||
const container = getScrollContainer(el) ?? window;
|
||||
const onScroll = (ev) => {
|
||||
if (!document.body.contains(el)) return;
|
||||
if (isTopVisible(el)) {
|
||||
|
@ -48,7 +48,7 @@ export function onScrollTop(el: Element, cb) {
|
|||
}
|
||||
|
||||
export function onScrollBottom(el: Element, cb) {
|
||||
const container = getScrollContainer(el) || window;
|
||||
const container = getScrollContainer(el) ?? window;
|
||||
const onScroll = (ev) => {
|
||||
if (!document.body.contains(el)) return;
|
||||
const pos = getScrollPosition(el);
|
||||
|
|
|
@ -44,7 +44,7 @@ export function uploadFile(
|
|||
reader.onload = async (ev) => {
|
||||
const ctx = reactive<Uploading>({
|
||||
id,
|
||||
name: name || file.name || "untitled",
|
||||
name: name ?? file.name ?? "untitled",
|
||||
progressMax: undefined,
|
||||
progressValue: undefined,
|
||||
img: window.URL.createObjectURL(file),
|
||||
|
@ -78,7 +78,7 @@ export function uploadFile(
|
|||
|
||||
const formData = new FormData();
|
||||
formData.append("force", "true");
|
||||
formData.append("file", resizedImage || file);
|
||||
formData.append("file", resizedImage ?? file);
|
||||
formData.append("name", ctx.name);
|
||||
if (folder) formData.append("folderId", folder);
|
||||
|
||||
|
|
|
@ -24,14 +24,14 @@ export function useNoteCapture(props: {
|
|||
const reaction = body.reaction;
|
||||
|
||||
if (body.emoji) {
|
||||
const emojis = note.value.emojis || [];
|
||||
const emojis = note.value.emojis ?? [];
|
||||
if (!emojis.includes(body.emoji)) {
|
||||
note.value.emojis = [...emojis, body.emoji];
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: reactionsプロパティがない場合ってあったっけ? なければ || {} は消せる
|
||||
const currentCount = note.value.reactions?.[reaction] || 0;
|
||||
// TODO: reactionsプロパティがない場合ってあったっけ?
|
||||
const currentCount = note.value.reactions?.[reaction] ?? 0;
|
||||
|
||||
note.value.reactions[reaction] = currentCount + 1;
|
||||
|
||||
|
@ -44,8 +44,8 @@ export function useNoteCapture(props: {
|
|||
case "unreacted": {
|
||||
const reaction = body.reaction;
|
||||
|
||||
// TODO: reactionsプロパティがない場合ってあったっけ? なければ || {} は消せる
|
||||
const currentCount = note.value.reactions?.[reaction] || 0;
|
||||
// TODO: reactionsプロパティがない場合ってあったっけ?
|
||||
const currentCount = note.value.reactions?.[reaction] ?? 0;
|
||||
|
||||
note.value.reactions[reaction] = Math.max(0, currentCount - 1);
|
||||
|
||||
|
|
|
@ -5,7 +5,7 @@ import { $i, isSignedIn } from "@/reactiveAccount";
|
|||
const lsCacheKey = isSignedIn ? `themes:${$i.id}` : "";
|
||||
|
||||
export function getThemes(): Theme[] {
|
||||
return JSON.parse(localStorage.getItem(lsCacheKey) || "[]");
|
||||
return JSON.parse(localStorage.getItem(lsCacheKey) ?? "[]");
|
||||
}
|
||||
|
||||
export async function fetchThemes(): Promise<void> {
|
||||
|
|
|
@ -146,7 +146,7 @@
|
|||
></i>
|
||||
</button>
|
||||
<!-- <button v-click-anime v-tooltip.noDelay.right="$instance.name ?? i18n.ts.instance" class="item _button instance" @click="openInstanceMenu">
|
||||
<img :src="$instance.iconUrl || $instance.faviconUrl || '/favicon.ico'" alt="" class="icon"/>
|
||||
<img :src="$instance.faviconUrl ?? $instance.iconUrl ?? '/favicon.ico'" alt="" class="icon"/>
|
||||
</button> -->
|
||||
<!-- <button v-click-anime v-tooltip.noDelay.right="`${i18n.ts.account}: @${$i.username}`" class="item _button account" @click="openAccountMenu">
|
||||
<MkAvatar :user="$i" class="account"/><MkAcct class="text" :user="$i"/>
|
||||
|
|
|
@ -41,8 +41,8 @@
|
|||
</p>
|
||||
</div>
|
||||
<progress
|
||||
:value="ctx.progressValue || 0"
|
||||
:max="ctx.progressMax || 0"
|
||||
:value="ctx.progressValue ?? 0"
|
||||
:max="ctx.progressMax ?? 0"
|
||||
:class="{
|
||||
initing: ctx.progressValue === undefined,
|
||||
waiting:
|
||||
|
|
|
@ -16,7 +16,11 @@
|
|||
<div v-if="meta" class="about">
|
||||
<div
|
||||
class="desc"
|
||||
v-html="meta.description || i18n.ts.introFirefish"
|
||||
v-html="
|
||||
meta.description !== ''
|
||||
? meta.description
|
||||
: i18n.ts.introFirefish
|
||||
"
|
||||
></div>
|
||||
</div>
|
||||
<div class="action">
|
||||
|
|
|
@ -86,10 +86,9 @@ import XKanban from "./kanban.vue";
|
|||
import { host, instanceName } from "@/config";
|
||||
import { search } from "@/scripts/search";
|
||||
import * as os from "@/os";
|
||||
import { instance } from "@/instance";
|
||||
import XSigninDialog from "@/components/MkSigninDialog.vue";
|
||||
import XSignupDialog from "@/components/MkSignupDialog.vue";
|
||||
import { ColdDeviceStorage, defaultStore } from "@/store";
|
||||
import { defaultStore } from "@/store";
|
||||
import { mainRouter } from "@/router";
|
||||
import type { PageMetadata } from "@/scripts/page-metadata";
|
||||
import { provideMetadataReceiver } from "@/scripts/page-metadata";
|
||||
|
@ -108,29 +107,11 @@ provideMetadataReceiver((info) => {
|
|||
}
|
||||
});
|
||||
|
||||
const announcements = {
|
||||
endpoint: "announcements",
|
||||
limit: 10,
|
||||
};
|
||||
const isTimelineAvailable =
|
||||
!instance.disableLocalTimeline ||
|
||||
!instance.disableRecommendedTimeline ||
|
||||
!instance.disableGlobalTimeline;
|
||||
const showMenu = ref(false);
|
||||
const isDesktop = ref(window.innerWidth >= DESKTOP_THRESHOLD);
|
||||
const narrow = ref(window.innerWidth < 1280);
|
||||
const meta = ref();
|
||||
|
||||
const keymap = computed(() => {
|
||||
return {
|
||||
d: () => {
|
||||
if (ColdDeviceStorage.get("syncDeviceDarkMode")) return;
|
||||
defaultStore.set("darkMode", !defaultStore.state.darkMode);
|
||||
},
|
||||
s: search,
|
||||
};
|
||||
});
|
||||
|
||||
const root = computed(() => mainRouter.currentRoute.value.name === "index");
|
||||
|
||||
os.api("meta", { detail: true }).then((res) => {
|
||||
|
@ -227,9 +208,6 @@ defineExpose({
|
|||
flex: 1;
|
||||
min-width: 0;
|
||||
|
||||
> .banner {
|
||||
}
|
||||
|
||||
> .contents {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
|
|
|
@ -26,7 +26,11 @@
|
|||
<div v-if="meta" class="about">
|
||||
<div
|
||||
class="desc"
|
||||
v-html="meta.description || i18n.ts.introFirefish"
|
||||
v-html="
|
||||
meta.description !== ''
|
||||
? meta.description
|
||||
: i18n.ts.introFirefish
|
||||
"
|
||||
></div>
|
||||
</div>
|
||||
<div class="action">
|
||||
|
|
|
@ -33,7 +33,7 @@
|
|||
>{{ instance.host }}</a
|
||||
>
|
||||
<p>
|
||||
{{ instance.softwareName || "?" }}
|
||||
{{ instance.softwareName ?? "?" }}
|
||||
{{ instance.softwareVersion }}
|
||||
</p>
|
||||
</div>
|
||||
|
|
|
@ -9,8 +9,8 @@
|
|||
<div :class="$style.iconContainer">
|
||||
<img
|
||||
:src="
|
||||
$instance.iconUrl ||
|
||||
$instance.faviconUrl ||
|
||||
$instance.faviconUrl ??
|
||||
$instance.iconUrl ??
|
||||
'/favicon.ico'
|
||||
"
|
||||
alt="Instance logo"
|
||||
|
|
Loading…
Reference in a new issue