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

@@ -13,7 +13,8 @@ SPDX-License-Identifier: AGPL-3.0-only
<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>
<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 }">
@@ -22,11 +23,16 @@ SPDX-License-Identifier: AGPL-3.0-only
<div class="title">
<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">
<button v-if="$i && !isEditingMemo && !memoDraft" class="_button add-note-button"
@click="showMemoTextarea">
<i class="ti ti-edit" /> {{ i18n.ts.addMemo }}
</button>
</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" />
<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"
/>
<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>
<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,7 +171,8 @@ 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" />
@@ -176,11 +207,13 @@ 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" />
@@ -725,8 +758,7 @@ onUnmounted(() => {
}
}
&.system > .field > .name {
}
&.system>.field>.name {}
}
>.status {

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,18 +96,30 @@ 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;
> .misskey {
width: 140px;
@media (max-width: 450px) {
width: 100px;
width: 130px;
}
}
}
> .emojis {
position: fixed;
bottom: 32px;
left: 35px;
> * {
margin-right: 8px;
}
@media (max-width: 1200px) {
display: none;
}
}
@@ -128,13 +134,13 @@ misskeyApiGet('federation/instances', {
}
}
.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);
@@ -146,7 +152,10 @@ misskeyApiGet('federation/instances', {
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;
@@ -195,7 +195,7 @@ defineExpose({
}
}
>.main {
.main {
flex: 1;
min-width: 0;
@@ -221,7 +221,7 @@ defineExpose({
}
}
>.menu-back {
.menu-back {
position: fixed;
z-index: 1001;
top: 0;
@@ -230,7 +230,7 @@ defineExpose({
height: 100vh;
}
>.menu {
.menu {
position: fixed;
z-index: 1001;
top: 0;
@@ -275,5 +275,4 @@ 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: