1
0
mirror of https://git.boykissers.com/pawkey/pawkey-sk.git synced 2025-12-20 04:04:16 +00:00

fix: fix stuff after merge

This commit is contained in:
Leafus
2025-06-01 06:26:43 +02:00
committed by Bluey Heeler
parent 5a5914be8d
commit 238aeed753
10 changed files with 490 additions and 431 deletions

View File

@@ -7,13 +7,13 @@ import { defineAsyncComponent, reactive, ref } from 'vue';
import * as Misskey from 'misskey-js';
import { apiUrl } from '@@/js/config.js';
import type { MenuItem, MenuButton } from '@/types/menu.js';
import { showSuspendedDialog } from '@/scripts/show-suspended-dialog.js';
import { showSuspendedDialog } from '@/utility/show-suspended-dialog.js';
import { i18n } from '@/i18n.js';
import { miLocalStorage } from '@/local-storage.js';
import { del, get, set } from '@/scripts/idb-proxy.js';
import { del, get, set } from '@/utility/idb-proxy.js';
import { waiting, popup, popupMenu, success, alert } from '@/os.js';
import { misskeyApi } from '@/scripts/misskey-api.js';
import { unisonReload, reloadChannel } from '@/scripts/unison-reload.js';
import { misskeyApi } from '@/utility/misskey-api.js';
import { unisonReload, reloadChannel } from '@/utility/unison-reload.js';
// TODO: 他のタブと永続化されたstateを同期

View File

@@ -76,7 +76,7 @@ import { ref } from 'vue';
import * as Misskey from 'misskey-js';
import { instanceName } from '@@/js/config.js';
import type { MenuItem } from '@/types/menu.js';
import sanitizeHtml from '@/scripts/sanitize-html.js';
import sanitizeHtml from '@/utility/sanitize-html.js';
import XSigninDialog from '@/components/MkSigninDialog.vue';
import XSignupDialog from '@/components/MkSignupDialog.vue';
import PwVisitorMusic from '@/components/PwVisitorMusic.vue';

View File

@@ -346,7 +346,7 @@ import { searchEngineMap } from '@/scripts/search-engine-map.js';
import { defaultStore } from '@/store.js';
import * as os from '@/os.js';
import { instance } from '@/instance.js';
import { misskeyApi } from '@/scripts/misskey-api.js';
import { misskeyApi } from '@/utility/misskey-api.js';
import { reloadAsk } from '@/scripts/reload-ask.js';
import { i18n } from '@/i18n.js';
import { definePageMetadata } from '@/scripts/page-metadata.js';

View File

@@ -35,9 +35,9 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkRadios v-model="overridedDeviceKind">
<template #label><SearchLabel>{{ i18n.ts.overridedDeviceKind }}</SearchLabel></template>
<option :value="null">{{ i18n.ts.auto }}</option>
<option value="smartphone"><i class="ti ti-device-mobile"/> {{ i18n.ts.smartphone }}</option>
<option value="tablet"><i class="ti ti-device-tablet"/> {{ i18n.ts.tablet }}</option>
<option value="desktop"><i class="ti ti-device-desktop"/> {{ i18n.ts.desktop }}</option>
<option value="smartphone">{{ i18n.ts.smartphone }}</option>
<option value="tablet">{{ i18n.ts.tablet }}</option>
<option value="desktop">{{ i18n.ts.desktop }}</option>
</MkRadios>
</SearchMarker>

View File

@@ -4,30 +4,36 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div class="_spacer" :style="{ '--MI_SPACER-w': narrow ? '800px' : '1100px', ...background }">
<div class="_spacer" :style="{ '--MI_SPACER-w': narrow ? '800px' : '1100px', ...background }">
<div ref="rootEl" class="ftskorzw" :class="{ wide: !narrow }" style="container-type: inline-size;">
<div class="main _gaps">
<MkInfo v-if="user.isSuspended" :warn="true">{{ i18n.ts.userSuspended }}</MkInfo>
<MkInfo v-if="user.isSilenced" :warn="true">{{ i18n.ts.userSilenced }}</MkInfo>
<div class="profile _gaps">
<MkAccountMoved v-if="user.movedTo" :movedTo="user.movedTo"/>
<MkRemoteCaution v-if="user.host != null" :href="user.url ?? user.uri!"/>
<MkInfo v-if="user.host == null && user.username.includes('.')">{{ i18n.ts.isSystemAccount }}</MkInfo>
<MkAccountMoved v-if="user.movedTo" :movedTo="user.movedTo" />
<MkRemoteCaution v-if="user.host != null" :href="user.url ?? user.uri!" />
<MkInfo v-if="user.host == null && user.username.includes('.')">{{ i18n.ts.isSystemAccount }}
</MkInfo>
<div :key="user.id" class="main _panel">
<div class="banner-container" :class="{ [$style.bannerContainerTall]: useTallBanner }">
<div ref="bannerEl" class="banner" :style="style"></div>
<div class="fade"></div>
<div class="title">
<MkUserName class="name" :user="user" :nowrap="true"/>
<MkUserName class="name" :user="user" :nowrap="true" />
<div class="bottom">
<span class="username"><MkAcct :user="user" :detail="true"/></span>
<span v-if="user.isAdmin" :title="i18n.ts.isAdmin" style="color: var(--MI_THEME-badge);"><i class="ti ti-shield"></i></span>
<span v-if="user.isLocked" :title="i18n.ts.isLocked"><i class="ti ti-lock"></i></span>
<span class="username">
<MkAcct :user="user" :detail="true" />
</span>
<span v-if="user.isAdmin" :title="i18n.ts.isAdmin"
style="color: var(--MI_THEME-badge);"><i class="ti ti-shield"></i></span>
<span v-if="user.isLocked" :title="i18n.ts.isLocked"><i
class="ti ti-lock"></i></span>
<span v-if="user.isBot" :title="i18n.ts.isBot"><i class="ti ti-robot"></i></span>
<button v-if="$i && !isEditingMemo && !memoDraft" class="_button add-note-button" @click="showMemoTextarea">
<i class="ti ti-edit"/> {{ i18n.ts.addMemo }}
<button v-if="$i && !isEditingMemo && !memoDraft" class="_button add-note-button"
@click="showMemoTextarea">
<i class="ti ti-edit" /> {{ i18n.ts.addMemo }}
</button>
</div>
</div>
@@ -41,19 +47,34 @@ SPDX-License-Identifier: AGPL-3.0-only
<li v-if="user.isBlocked && $i.isModerator">{{ i18n.ts.blockingYou }}</li>
</ul>
<div :class="$style.actions" class="actions">
<button :class="$style.actionsMenu" class="menu _button" @click="menu"><i class="ti ti-dots"></i></button>
<MkFollowButton v-if="$i?.id != user.id" v-model:user="user" :class="$style.actionsFollow" :disabled="disableFollowControls" :inline="true" :transparent="false" :full="true" class="koudoku" @update:wait="onFollowButtonDisabledChanged"/>
<div v-if="hasFollowRequest" :class="$style.actionsBanner">{{ i18n.ts.receiveFollowRequest }}</div>
<MkButton v-if="hasFollowRequest" :class="$style.actionsAccept" :disabled="disableFollowControls" :inline="true" :transparent="false" :full="true" rounded primary @click="acceptFollowRequest"><i class="ti ti-check"/> {{ i18n.ts.accept }}</MkButton>
<MkButton v-if="hasFollowRequest" :class="$style.actionsReject" :disabled="disableFollowControls" :inline="true" :transparent="false" :full="true" rounded danger @click="rejectFollowRequest"><i class="ti ti-x"/> {{ i18n.ts.reject }}</MkButton>
<button :class="$style.actionsMenu" class="menu _button" @click="menu"><i
class="ti ti-dots"></i></button>
<MkFollowButton v-if="$i?.id != user.id" v-model:user="user"
:class="$style.actionsFollow" :disabled="disableFollowControls" :inline="true"
:transparent="false" :full="true" class="koudoku"
@update:wait="onFollowButtonDisabledChanged" />
<div v-if="hasFollowRequest" :class="$style.actionsBanner">{{
i18n.ts.receiveFollowRequest }}</div>
<MkButton v-if="hasFollowRequest" :class="$style.actionsAccept"
:disabled="disableFollowControls" :inline="true" :transparent="false" :full="true"
rounded primary @click="acceptFollowRequest"><i class="ti ti-check" /> {{
i18n.ts.accept }}</MkButton>
<MkButton v-if="hasFollowRequest" :class="$style.actionsReject"
:disabled="disableFollowControls" :inline="true" :transparent="false" :full="true"
rounded danger @click="rejectFollowRequest"><i class="ti ti-x" /> {{ i18n.ts.reject
}}</MkButton>
</div>
</div>
<MkAvatar class="avatar" :class="{ [$style.avatarTall]: useTallBanner }" :user="user" indicator/>
<MkAvatar class="avatar" :class="{ [$style.avatarTall]: useTallBanner }" :user="user"
indicator />
<div class="title">
<MkUserName :user="user" :nowrap="false" class="name"/>
<MkUserName :user="user" :nowrap="false" class="name" />
<div class="bottom">
<span class="username"><MkAcct :user="user" :detail="true"/></span>
<span v-if="user.isAdmin" :title="i18n.ts.isAdmin" style="color: var(--MI_THEME-badge);"><i class="ti ti-shield"></i></span>
<span class="username">
<MkAcct :user="user" :detail="true" />
</span>
<span v-if="user.isAdmin" :title="i18n.ts.isAdmin"
style="color: var(--MI_THEME-badge);"><i class="ti ti-shield"></i></span>
<span v-if="user.isLocked" :title="i18n.ts.isLocked"><i class="ti ti-lock"></i></span>
<span v-if="user.isBot" :title="i18n.ts.isBot"><i class="ti ti-robot"></i></span>
</div>
@@ -61,42 +82,44 @@ SPDX-License-Identifier: AGPL-3.0-only
<div v-if="user.followedMessage != null" class="followedMessage">
<MkFukidashi class="fukidashi" :tail="narrow ? 'none' : 'left'" negativeMargin>
<div class="messageHeader">{{ i18n.ts.messageToFollower }}</div>
<div><MkSparkle><Mfm :plain="true" :text="user.followedMessage" :author="user" class="_selectable"/></MkSparkle></div>
<div>
<MkSparkle>
<Mfm :plain="true" :text="user.followedMessage" :author="user"
class="_selectable" />
</MkSparkle>
</div>
</MkFukidashi>
</div>
<div v-if="user.roles.length > 0" class="roles">
<span v-for="role in user.roles" :key="role.id" v-tooltip="role.description" class="role" :style="{ '--color': role.color }">
<span v-for="role in user.roles" :key="role.id" v-tooltip="role.description" class="role"
:style="{ '--color': role.color }">
<MkA v-adaptive-bg :to="`/roles/${role.id}`">
<img v-if="role.iconUrl" style="height: 1.3em; vertical-align: -22%;" :src="role.iconUrl"/>
<img v-if="role.iconUrl" style="height: 1.3em; vertical-align: -22%;"
:src="role.iconUrl" />
{{ role.name }}
</MkA>
</span>
</div>
<div v-if="iAmModerator" class="moderationNote">
<MkTextarea v-if="editModerationNote || (moderationNote != null && moderationNote !== '')" v-model="moderationNote" manualSave>
<MkTextarea v-if="editModerationNote || (moderationNote != null && moderationNote !== '')"
v-model="moderationNote" manualSave>
<template #label>{{ i18n.ts.moderationNote }}</template>
<template #caption>{{ i18n.ts.moderationNoteDescription }}</template>
</MkTextarea>
<div v-else>
<MkButton small @click="editModerationNote = true">{{ i18n.ts.addModerationNote }}</MkButton>
<MkButton small @click="editModerationNote = true">{{ i18n.ts.addModerationNote }}
</MkButton>
</div>
</div>
<div v-if="isEditingMemo || memoDraft" class="memo" :class="{'no-memo': !memoDraft}">
<div class="heading" v-text="i18n.ts.memo"/>
<textarea
ref="memoTextareaEl"
v-model="memoDraft"
rows="1"
@focus="isEditingMemo = true"
@blur="updateMemo"
@input="adjustMemoTextarea"
/>
<div v-if="isEditingMemo || memoDraft" class="memo" :class="{ 'no-memo': !memoDraft }">
<div class="heading" v-text="i18n.ts.memo" />
<textarea ref="memoTextareaEl" v-model="memoDraft" rows="1" @focus="isEditingMemo = true"
@blur="updateMemo" @input="adjustMemoTextarea" />
</div>
<div class="description">
<MkOmit>
<Mfm v-if="user.description" :text="user.description" :isBlock="true" :isNote="false" :author="user" class="_selectable"/>
<Mfm v-if="user.description" :text="user.description" :isBlock="true" :isNote="false"
:author="user" class="_selectable" />
<p v-else class="empty">{{ i18n.ts.noAccountDescription }}</p>
</MkOmit>
</div>
<div class="fields system">
<dl v-if="user.location" class="field">
@@ -105,21 +128,28 @@ SPDX-License-Identifier: AGPL-3.0-only
</dl>
<dl v-if="user.birthday" class="field">
<dt class="name"><i class="ti ti-cake ti-fw"></i> {{ i18n.ts.birthday }}</dt>
<dd class="value">{{ user.birthday.replace('-', '/').replace('-', '/') }} ({{ i18n.tsx.yearsOld({ age }) }})</dd>
<dd class="value">{{ user.birthday.replace('-', '/').replace('-', '/') }} ({{
i18n.tsx.yearsOld({ age }) }})
</dd>
</dl>
<dl class="field">
<dt class="name"><i class="ti ti-calendar ti-fw"></i> {{ i18n.ts.registeredDate }}</dt>
<dd class="value">{{ dateString(user.createdAt) }} (<MkTime :time="user.createdAt"/>)</dd>
<dd class="value">{{ dateString(user.createdAt) }} (
<MkTime :time="user.createdAt" />)
</dd>
</dl>
</div>
<div v-if="user.fields.length > 0" class="fields">
<dl v-for="(field, i) in user.fields" :key="i" class="field">
<dt class="name">
<Mfm :text="field.name" :author="user" :plain="true" :colored="false" class="_selectable"/>
<Mfm :text="field.name" :author="user" :plain="true" :colored="false"
class="_selectable" />
</dt>
<dd class="value">
<Mfm :text="field.value" :author="user" :colored="false" class="_selectable"/>
<i v-if="user.verifiedLinks.includes(field.value)" v-tooltip:dialog="i18n.ts.verifiedLink" class="ti ti-circle-check" :class="$style.verifiedLink"></i>
<Mfm :text="field.value" :author="user" :colored="false" class="_selectable" />
<i v-if="user.verifiedLinks.includes(field.value)"
v-tooltip:dialog="i18n.ts.verifiedLink" class="ti ti-circle-check"
:class="$style.verifiedLink"></i>
</dd>
</dl>
</div>
@@ -141,19 +171,20 @@ SPDX-License-Identifier: AGPL-3.0-only
</div>
<div class="contents _gaps">
<MkInfo v-if="user.pinnedNotes.length === 0 && $i?.id === user.id">{{ i18n.ts.userPagePinTip }}</MkInfo>
<MkInfo v-if="user.pinnedNotes.length === 0 && $i?.id === user.id">{{ i18n.ts.userPagePinTip }}
</MkInfo>
<template v-if="narrow">
<MkLazy v-if="user.musicUrl">
<XProfileMusic :key="user.id" :user="user"/>
<XProfileMusic :key="user.id" :user="user" />
</MkLazy>
<MkLazy>
<XFiles :key="user.id" :user="user" :collapsed="true" @unfold="emit('unfoldFiles')"/>
<XFiles :key="user.id" :user="user" :collapsed="true" @unfold="emit('unfoldFiles')" />
</MkLazy>
<MkLazy>
<XActivity :key="user.id" :user="user" :collapsed="true"/>
<XActivity :key="user.id" :user="user" :collapsed="true" />
</MkLazy>
<MkLazy v-if="user.listenbrainz && listenbrainzdata">
<XListenBrainz :key="user.id" :user="user" :collapsed="true"/>
<XListenBrainz :key="user.id" :user="user" :collapsed="true" />
</MkLazy>
</template>
<!-- <div v-if="!disableNotes">
@@ -176,27 +207,29 @@ SPDX-License-Identifier: AGPL-3.0-only
<MkLazy>
<div v-if="noteview === 'pinned'" class="_gaps">
<div v-if="user.pinnedNotes.length < 1" class="_fullinfo">
<img :src="infoImageUrl" draggable="false" aria-hidden="true" :alt="i18n.ts.noNotes"/>
<img :src="infoImageUrl" draggable="false" aria-hidden="true"
:alt="i18n.ts.noNotes" />
<div>{{ i18n.ts.noNotes }}</div>
</div>
<div v-else class="_panel">
<DynamicNote v-for="note of user.pinnedNotes" :key="note.id" class="note" :class="$style.pinnedNote" :note="note" :pinned="true"/>
<DynamicNote v-for="note of user.pinnedNotes" :key="note.id" class="note"
:class="$style.pinnedNote" :note="note" :pinned="true" />
</div>
</div>
<MkNotes v-else :class="$style.tl" :noGap="true" :pagination="AllPagination"/>
<MkNotes v-else :class="$style.tl" :noGap="true" :pagination="AllPagination" />
</MkLazy>
</MkStickyContainer>
</div>
</div>
<div v-if="!narrow" class="sub _gaps" style="container-type: inline-size;">
<XFiles :key="user.id" :user="user" @unfold="emit('unfoldFiles')"/>
<XActivity :key="user.id" :user="user"/>
<XListenBrainz v-if="user.listenbrainz && listenbrainzdata" :key="user.id" :user="user"/>
<XProfileMusic v-if="user.musicUrl" :key="user.id" :user="user" :collapsed="true"/>
<XFiles :key="user.id" :user="user" @unfold="emit('unfoldFiles')" />
<XActivity :key="user.id" :user="user" />
<XListenBrainz v-if="user.listenbrainz && listenbrainzdata" :key="user.id" :user="user" />
<XProfileMusic v-if="user.musicUrl" :key="user.id" :user="user" :collapsed="true" />
</div>
</div>
<div class="background"></div>
</div>
</div>
</template>
<script lang="ts" setup>
@@ -277,7 +310,7 @@ const noteview = ref<string | null>(props.user.pinnedNotes.length ? 'pinned' : n
const listenbrainzdata = ref(false);
if (props.user.listenbrainz) {
(async function() {
(async function () {
try {
const response = await window.fetch(`https://api.listenbrainz.org/1/user/${props.user.listenbrainz}/playing-now`, {
method: 'GET',
@@ -336,11 +369,11 @@ const style = computed(() => {
if (props.user.bannerUrl == null) return {};
if (prefer.s.disableShowingAnimatedImages) {
return {
backgroundImage: `url(${ getStaticImageUrl(props.user.bannerUrl) })`,
backgroundImage: `url(${getStaticImageUrl(props.user.bannerUrl)})`,
};
} else {
return {
backgroundImage: `url(${ props.user.bannerUrl })`,
backgroundImage: `url(${props.user.bannerUrl})`,
};
}
});
@@ -461,7 +494,7 @@ onUnmounted(() => {
</script>
<style lang="scss" scoped>
.background{
.background {
position: fixed;
z-index: -1;
background: var(--backgroundImageStatic);
@@ -479,28 +512,28 @@ onUnmounted(() => {
.ftskorzw {
> .main {
>.main {
> .punished {
>.punished {
font-size: 0.8em;
padding: 16px;
}
> .profile {
>.profile {
> .main {
>.main {
position: relative;
overflow: clip;
background: color-mix(in srgb, var(--MI_THEME-panel) 65%, transparent);
> .banner-container {
>.banner-container {
position: relative;
height: 250px;
overflow: clip;
background-size: cover;
background-position: center;
> .banner {
>.banner {
height: 100%;
background-color: #4c5e6d;
background-size: cover;
@@ -509,7 +542,7 @@ onUnmounted(() => {
will-change: background-position;
}
> .fade {
>.fade {
position: absolute;
bottom: 0;
left: 0;
@@ -518,7 +551,7 @@ onUnmounted(() => {
background: linear-gradient(transparent, rgba(#000, 0.7));
}
> .actions {
>.actions {
position: absolute;
top: 12px;
right: 12px;
@@ -528,7 +561,7 @@ onUnmounted(() => {
padding: 8px;
border-radius: var(--MI-radius-lg);
> .menu {
>.menu {
vertical-align: bottom;
height: 31px;
width: 31px;
@@ -537,13 +570,13 @@ onUnmounted(() => {
font-size: 16px;
}
> .koudoku {
>.koudoku {
margin-left: 4px;
vertical-align: bottom;
}
}
> .title {
>.title {
position: absolute;
bottom: 0;
left: 0;
@@ -552,7 +585,7 @@ onUnmounted(() => {
box-sizing: border-box;
color: #fff;
> .name {
>.name {
display: block;
margin: -10px;
padding: 10px;
@@ -562,8 +595,8 @@ onUnmounted(() => {
filter: drop-shadow(0 0 4px #000);
}
> .bottom {
> * {
>.bottom {
>* {
display: inline-block;
margin-right: 16px;
line-height: 20px;
@@ -574,7 +607,7 @@ onUnmounted(() => {
}
}
> .add-note-button {
>.add-note-button {
background: rgba(0, 0, 0, 0.2);
color: #fff;
-webkit-backdrop-filter: var(--MI-blur, blur(8px));
@@ -587,15 +620,15 @@ onUnmounted(() => {
}
}
> .title {
>.title {
display: none;
text-align: center;
padding: 50px 8px 16px 8px;
font-weight: bold;
border-bottom: solid 0.5px var(--MI_THEME-divider);
> .bottom {
> * {
>.bottom {
>* {
display: inline-block;
margin-right: 8px;
opacity: 0.8;
@@ -603,7 +636,7 @@ onUnmounted(() => {
}
}
> .avatar {
>.avatar {
display: block;
position: absolute;
top: 170px;
@@ -614,10 +647,10 @@ onUnmounted(() => {
filter: drop-shadow(1px 1px 3px rgba(#000, 0.2));
}
> .followedMessage {
>.followedMessage {
padding: 24px 24px 0 154px;
> .fukidashi {
>.fukidashi {
display: block;
--fukidashi-bg: color-mix(in srgb, var(--MI_THEME-accent), var(--MI_THEME-panel) 85%);
--fukidashi-radius: 16px;
@@ -630,14 +663,14 @@ onUnmounted(() => {
}
}
> .roles {
>.roles {
padding: 24px 24px 0 154px;
font-size: 0.95em;
display: flex;
flex-wrap: wrap;
gap: 8px;
> .role {
>.role {
border: solid 1px var(--color, var(--MI_THEME-divider));
border-radius: var(--MI-radius-ellipse);
margin-right: 4px;
@@ -645,11 +678,11 @@ onUnmounted(() => {
}
}
> .moderationNote {
>.moderationNote {
margin: 12px 24px 0 154px;
}
> .memo {
>.memo {
margin: 12px 24px 0 154px;
background: transparent;
color: var(--MI_THEME-fg);
@@ -658,7 +691,7 @@ onUnmounted(() => {
padding: 8px;
line-height: 0;
> .heading {
>.heading {
text-align: left;
color: color(from var(--MI_THEME-fg) srgb r g b / 0.5);
line-height: 1.5;
@@ -682,22 +715,22 @@ onUnmounted(() => {
}
}
> .description {
>.description {
padding: 24px 24px 24px 154px;
font-size: 0.95em;
> .empty {
>.empty {
margin: 0;
opacity: 0.5;
}
}
> .fields {
>.fields {
padding: 24px;
font-size: 0.9em;
border-top: solid 0.5px var(--MI_THEME-divider);
> .field {
>.field {
display: flex;
padding: 0;
margin: 0;
@@ -707,7 +740,7 @@ onUnmounted(() => {
margin-bottom: 8px;
}
> .name {
>.name {
width: 30%;
overflow: hidden;
white-space: nowrap;
@@ -716,7 +749,7 @@ onUnmounted(() => {
text-align: center;
}
> .value {
>.value {
width: 70%;
overflow: hidden;
white-space: nowrap;
@@ -725,16 +758,15 @@ onUnmounted(() => {
}
}
&.system > .field > .name {
}
&.system>.field>.name {}
}
> .status {
>.status {
display: flex;
padding: 24px;
border-top: solid 0.5px var(--MI_THEME-divider);
> a {
>a {
flex: 1;
text-align: center;
@@ -746,12 +778,12 @@ onUnmounted(() => {
text-decoration: none;
}
> b {
>b {
display: block;
line-height: 16px;
}
> span {
>span {
font-size: 70%;
}
}
@@ -759,8 +791,8 @@ onUnmounted(() => {
}
}
> .contents {
> .content {
>.contents {
>.content {
margin-bottom: var(--MI-margin);
}
}
@@ -770,12 +802,12 @@ onUnmounted(() => {
display: flex;
width: 100%;
> .main {
>.main {
width: 100%;
min-width: 0;
}
> .sub {
>.sub {
max-width: 350px;
min-width: 350px;
margin-left: var(--MI-margin);
@@ -785,25 +817,25 @@ onUnmounted(() => {
@container (max-width: 500px) {
.ftskorzw {
> .main {
> .profile > .main {
> .banner-container {
>.main {
>.profile>.main {
>.banner-container {
height: 140px;
> .fade {
>.fade {
display: none;
}
> .title {
>.title {
display: none;
}
}
> .title {
>.title {
display: block;
}
> .avatar {
>.avatar {
top: 90px;
left: 0;
right: 0;
@@ -812,39 +844,39 @@ onUnmounted(() => {
margin: auto;
}
> .followedMessage {
>.followedMessage {
padding: 16px 16px 0 16px;
}
> .roles {
>.roles {
padding: 16px 16px 0 16px;
justify-content: center;
}
> .moderationNote {
>.moderationNote {
margin: 16px 16px 0 16px;
}
> .memo {
>.memo {
margin: 16px 16px 0 16px;
}
> .description {
>.description {
padding: 16px;
text-align: center;
}
> .fields {
>.fields {
padding: 16px;
}
> .status {
>.status {
padding: 16px;
}
}
> .contents {
> .nav {
>.contents {
>.nav {
font-size: 80%;
}
}
@@ -868,7 +900,7 @@ onUnmounted(() => {
backdrop-filter: var(--MI-blur, blur(15px));
border-radius: var(--MI-radius-sm);
> button {
>button {
border-radius: var(--MI-radius-sm);
margin-left: 0.4rem;
margin-right: 0.4rem;
@@ -891,7 +923,7 @@ onUnmounted(() => {
padding: 0;
margin: 0;
> * {
>* {
padding: 4px 8px;
color: #fff;
background: rgba(0, 0, 0, 0.7);

View File

@@ -4,9 +4,8 @@ SPDX-License-Identifier: AGPL-3.0-only
-->
<template>
<div v-if="meta" :class="$style.root">
<MkFeaturedPhotos :class="$style.bg"/>
<XTimeline v-if="meta.policies.ltlAvailable" :class="$style.tl"/>
<div v-if="meta" class="rsqzvsbo">
<MkFeaturedPhotos class="bg"/>
<div class="logo-wrapper">
<!-- <div class="powered-by">Powered by</div> -->
<img :src="misskeysvg" class="misskey"/>
@@ -37,7 +36,7 @@ import { ref } from 'vue';
import * as Misskey from 'misskey-js';
import MkFeaturedPhotos from '@/components/MkFeaturedPhotos.vue';
import misskeysvg from '/client-assets/pawkey.png';
import { misskeyApiGet } from '@/scripts/misskey-api.js';
import { misskeyApiGet } from '@/utility/misskey-api.js';
import MkVisitorDashboard from '@/components/MkVisitorDashboard.vue';
import { getProxiedImageUrl } from '@/utility/media-proxy.js';
import { instance as meta } from '@/instance.js';
@@ -61,22 +60,17 @@ misskeyApiGet('federation/instances', {
});
</script>
<style lang="scss" module>
.root {
height: 100cqh;
overflow: auto;
overscroll-behavior: contain;
}
.bg {
<style lang="scss" scoped>
.rsqzvsbo {
> .bg {
position: fixed;
top: 0;
right: 0;
width: 100%;
width: 100vw;
height: 100vh;
}
}
.tl {
> .tl {
position: fixed;
top: 0;
bottom: 0;
@@ -94,7 +88,7 @@ misskeyApiGet('federation/instances', {
}
}
.logoWrapper {
> .logo-wrapper {
position: fixed;
top: 36px;
left: 36px;
@@ -102,20 +96,32 @@ misskeyApiGet('federation/instances', {
color: #fff;
user-select: none;
pointer-events: none;
}
.poweredBy {
color: var(--MI_THEME-fgOnAccent);
> .powered-by {
margin-bottom: 2px;
}
.misskey {
width: 120px;
@media (max-width: 450px) {
width: 100px;
}
}
> .misskey {
width: 140px;
@media (max-width: 450px) {
width: 130px;
}
}
}
> .emojis {
position: fixed;
bottom: 32px;
left: 35px;
> * {
margin-right: 8px;
}
@media (max-width: 1200px) {
display: none;
}
}
> .contents {
position: relative;
@@ -126,15 +132,15 @@ misskeyApiGet('federation/instances', {
@media (max-width: 1200px) {
margin: auto;
}
}
}
.federation {
> .federation {
position: fixed;
bottom: 16px;
left: 0;
right: 0;
margin: auto;
background: color(from var(--MI_THEME-panel) srgb r g b / 0.5);
background: var(--MI_THEME-acrylicPanel);
-webkit-backdrop-filter: var(--MI-blur, blur(15px));
backdrop-filter: var(--MI-blur, blur(15px));
border-radius: var(--MI-radius-ellipse);
@@ -145,8 +151,11 @@ misskeyApiGet('federation/instances', {
@media (max-width: 900px) {
display: none;
}
}
}
</style>
<style lang="scss" module>
.federationInstance {
display: inline-flex;
align-items: center;
@@ -155,13 +164,13 @@ misskeyApiGet('federation/instances', {
margin: 0 10px 0 0;
background: var(--MI_THEME-panel);
border-radius: var(--MI-radius-ellipse);
}
.federationInstanceIcon {
> :global(.icon) {
display: inline-block;
width: 20px;
height: 20px;
margin-right: 5px;
border-radius: var(--MI-radius-ellipse);
}
}
</style>

View File

@@ -420,7 +420,7 @@ function getPointerEvents() {
#devTicker {
position: fixed;
bottom: 0;
bottom: 10px;
left: 0;
z-index: 2147483647;
border-radius: 10px;

View File

@@ -83,10 +83,6 @@ const isVideo = computed(() => {
const url = instance.backgroundImageUrl.toLowerCase();
return url.endsWith('.mp4') || url.endsWith('.webm') || url.endsWith('.ogg');
});
defineExpose({
showMenu: showMenu,
});
</script>
<style>
@@ -137,6 +133,11 @@ defineExpose({
min-width: 0;
}
.content {
flex: 1;
overflow: auto;
}
.homeButton {
position: fixed;
z-index: 1000;
@@ -159,7 +160,6 @@ defineExpose({
z-index: 1;
overflow-y: scroll;
background: var(--MI_THEME-accent);
}
>.banner {
position: absolute;
@@ -193,9 +193,9 @@ defineExpose({
max-height: 100%;
overflow: auto;
}
}
}
>.main {
.main {
flex: 1;
min-width: 0;
@@ -219,18 +219,18 @@ defineExpose({
}
}
}
}
}
>.menu-back {
.menu-back {
position: fixed;
z-index: 1001;
top: 0;
left: 0;
width: 100vw;
height: 100vh;
}
}
>.menu {
.menu {
position: fixed;
z-index: 1001;
top: 0;
@@ -257,7 +257,7 @@ defineExpose({
>.action {
padding: 16px;
>button {
> button {
display: block;
width: 100%;
padding: 10px;
@@ -274,6 +274,5 @@ defineExpose({
}
}
}
}
}
</style>

View File

@@ -0,0 +1,19 @@
/*
* SPDX-FileCopyrightText: dakkar and other Sharkey contributors
* SPDX-License-Identifier: AGPL-3.0-only
*/
import original from 'sanitize-html';
export default function sanitizeHtml(str: string | null): string | null {
if (str == null) return str;
return original(str, {
allowedTags: original.defaults.allowedTags.concat(['img', 'audio', 'video', 'center', 'details', 'summary']),
allowedAttributes: {
...original.defaults.allowedAttributes,
a: original.defaults.allowedAttributes.a.concat(['style']),
img: original.defaults.allowedAttributes.img.concat(['style']),
'*': (original.defaults.allowedAttributes['*'] || []).concat(['style']),
},
});
}

6
pnpm-lock.yaml generated
View File

@@ -675,7 +675,7 @@ importers:
version: 2.1.1
'@iconify/vue':
specifier: ^4.3.0
version: 4.3.0(vue@3.5.12(typescript@5.6.3))
version: 4.3.0(vue@3.5.14(typescript@5.8.3))
'@mcaptcha/vanilla-glue':
specifier: 0.1.0-alpha-3
version: 0.1.0-alpha-3
@@ -12081,10 +12081,10 @@ snapshots:
'@iconify/types@2.0.0': {}
'@iconify/vue@4.3.0(vue@3.5.12(typescript@5.6.3))':
'@iconify/vue@4.3.0(vue@3.5.14(typescript@5.8.3))':
dependencies:
'@iconify/types': 2.0.0
vue: 3.5.12(typescript@5.6.3)
vue: 3.5.14(typescript@5.8.3)
'@img/sharp-darwin-arm64@0.34.1':
optionalDependencies: