Compare commits

..

2 Commits

Author SHA1 Message Date
Natty b50249da02
Frontend: Changed powered by to "Magnetar"
ci/woodpecker/push/ociImagePush Pipeline was successful Details
2023-12-28 00:35:10 +01:00
Natty 7fbcc4ec19
Frontend: Removed dependence on Calckey note resolving and avatars 2023-12-28 00:34:52 +01:00
60 changed files with 263 additions and 228 deletions

View File

@ -20,7 +20,7 @@ magnetar-dev.local {
} }
@render_html { @render_html {
not path /api* /proxy* /files* /avatar* /identicon* /streaming not path /api* /proxy* /files* /avatar* /identicon*
header Accept text/html* header Accept text/html*
} }

View File

@ -853,7 +853,6 @@ export type Endpoints = {
}; };
res: Note[]; res: Note[];
}; };
"notes/polls/recommendation": { req: TODO; res: TODO };
"notes/polls/vote": { "notes/polls/vote": {
req: { noteId: Note["id"]; choice: number }; req: { noteId: Note["id"]; choice: number };
res: null; res: null;
@ -887,7 +886,6 @@ export type Endpoints = {
}; };
"notes/search-by-tag": { req: TODO; res: TODO }; "notes/search-by-tag": { req: TODO; res: TODO };
"notes/search": { req: TODO; res: TODO }; "notes/search": { req: TODO; res: TODO };
"notes/show": { req: { noteId: Note["id"] }; res: Note };
"notes/state": { req: TODO; res: TODO }; "notes/state": { req: TODO; res: TODO };
"notes/timeline": { "notes/timeline": {
req: { req: {

View File

@ -3,13 +3,12 @@ import * as misskey from "calckey-js";
import { i18n } from "./i18n"; import { i18n } from "./i18n";
import { del, get, set } from "@/scripts/idb-proxy"; import { del, get, set } from "@/scripts/idb-proxy";
import { apiUrl } from "@/config"; import { apiUrl } from "@/config";
import { waiting, api, popup, popupMenu, success, alert } from "@/os"; import { alert, api, popup, popupMenu, success, waiting } from "@/os";
import { unisonReload, reloadChannel } from "@/scripts/unison-reload"; import { reloadChannel, unisonReload } from "@/scripts/unison-reload";
// TODO: 他のタブと永続化されたstateを同期 // TODO: 他のタブと永続化されたstateを同期
type Account = misskey.entities.MeDetailed; type Account = misskey.entities.MeDetailed;
const accountData = localStorage.getItem("account"); const accountData = localStorage.getItem("account");
// TODO: 外部からはreadonlyに // TODO: 外部からはreadonlyに

View File

@ -1,7 +1,7 @@
<template> <template>
<div class="defgtij"> <div class="defgtij">
<div v-for="user in users" :key="user.id" class="avatar-holder"> <div v-for="user in users" :key="user.id" class="avatar-holder">
<MkAvatar :user="user" class="avatar" /> <MagAvatar :user="user" class="avatar" />
</div> </div>
</div> </div>
</template> </template>
@ -9,7 +9,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, ref, watch } from "vue"; import { onMounted, ref, watch } from "vue";
import * as os from "@/os"; import * as os from "@/os";
import { packed, endpoints } from "magnetar-common"; import { endpoints, packed } from "magnetar-common";
const props = defineProps<{ const props = defineProps<{
userIds: string[]; userIds: string[];

View File

@ -71,7 +71,7 @@
</div> </div>
</div> </div>
<div v-if="collapsedReply && appearNote.parent_note" class="info"> <div v-if="collapsedReply && appearNote.parent_note" class="info">
<MkAvatar class="avatar" :user="appearNote.parent_note.user" /> <MagAvatar class="avatar" :user="appearNote.parent_note.user" />
<MkUserName <MkUserName
class="username" class="username"
:user="appearNote.parent_note.user" :user="appearNote.parent_note.user"
@ -95,7 +95,7 @@
> >
<div class="main"> <div class="main">
<div class="header-container"> <div class="header-container">
<MkAvatar class="avatar" :user="appearNote.user" /> <MagAvatar class="avatar" :user="appearNote.user" />
<XNoteHeader class="header" :note="appearNote" /> <XNoteHeader class="header" :note="appearNote" />
</div> </div>
<div class="body"> <div class="body">

View File

@ -117,7 +117,7 @@
{{ item.description }} {{ item.description }}
</div> </div>
<div class="user"> <div class="user">
<MkAvatar <MagAvatarResolvingProxy
:user="item.user" :user="item.user"
class="avatar" class="avatar"
:show-indicator="true" :show-indicator="true"

View File

@ -1,6 +1,6 @@
<template> <template>
<div v-size="{ min: [350, 500] }" class="yohlumlk"> <div v-size="{ min: [350, 500] }" class="yohlumlk">
<MkAvatar class="avatar" :user="note.user" /> <MagAvatar class="avatar" :user="note.user" />
<div class="main"> <div class="main">
<XNoteHeader class="header" :note="note" :mini="true" /> <XNoteHeader class="header" :note="note" :mini="true" />
<div class="body"> <div class="body">

View File

@ -20,7 +20,7 @@
:style="{ cursor: expandOnNoteClick ? 'pointer' : '' }" :style="{ cursor: expandOnNoteClick ? 'pointer' : '' }"
> >
<div class="avatar-container"> <div class="avatar-container">
<MkAvatar class="avatar" :user="appearNote.user" /> <MagAvatar class="avatar" :user="appearNote.user" />
<div <div
v-if="!conversation || replies.length > 0" v-if="!conversation || replies.length > 0"
class="line" class="line"

View File

@ -60,13 +60,13 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, ref } from "vue"; import { computed, ref, toRaw } from "vue";
import { sum } from "@/scripts/array"; import { sum } from "@/scripts/array";
import { pleaseLogin } from "@/scripts/please-login"; import { pleaseLogin } from "@/scripts/please-login";
import * as os from "@/os"; import * as os from "@/os";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { useInterval } from "@/scripts/use-interval"; import { useInterval } from "@/scripts/use-interval";
import { packed } from "magnetar-common"; import { endpoints, packed } from "magnetar-common";
const props = defineProps<{ const props = defineProps<{
note: packed.PackNoteMaybeFull & { poll: {} }; note: packed.PackNoteMaybeFull & { poll: {} };
@ -133,17 +133,14 @@ async function refresh() {
os.api("ap/show", { uri: props.note.uri }) os.api("ap/show", { uri: props.note.uri })
.then((obj) => { .then((obj) => {
if (obj && obj.type === "Note" && obj.object.poll) { if (obj && obj.type === "Note") {
props.note.poll = { os.magApi(
...props.note.poll, endpoints.GetNoteById,
expires_at: obj.object.poll.expiresAt, { attachments: true },
multiple_choice: obj.object.poll.multiple, { id: obj.object.id }
options: obj.object.poll.choices?.map((c) => ({ ).then((n) => {
title: c.text, props.note.poll = { ...toRaw(props.note.poll), ...n.poll };
votes_count: c.votes, });
voted: c.isVoted,
})),
};
} }
}) })
.catch((err) => { .catch((err) => {

View File

@ -42,7 +42,7 @@
{{ i18n.ts.followRequestYou }} {{ i18n.ts.followRequestYou }}
</span> </span>
</div> </div>
<MkAvatar <MagAvatar
class="avatar" class="avatar"
:user="user" :user="user"
:disable-preview="true" :disable-preview="true"

View File

@ -6,7 +6,7 @@
class="info" class="info"
:to="`/user-info/${report.targetUserId}`" :to="`/user-info/${report.targetUserId}`"
> >
<MkAvatar <MagAvatarResolvingProxy
class="avatar" class="avatar"
:user="report.targetUser" :user="report.targetUser"
:show-indicator="true" :show-indicator="true"
@ -68,7 +68,6 @@
import MkButton from "@/components/MkButton.vue"; import MkButton from "@/components/MkButton.vue";
import MkSwitch from "@/components/form/switch.vue"; import MkSwitch from "@/components/form/switch.vue";
import MkKeyValue from "@/components/MkKeyValue.vue"; import MkKeyValue from "@/components/MkKeyValue.vue";
import { acct, userPage } from "@/filters/user";
import * as os from "@/os"; import * as os from "@/os";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";

View File

@ -8,7 +8,12 @@ export default defineComponent({
props: { props: {
items: { items: {
type: Array as PropType< type: Array as PropType<
{ id: string; createdAt: string; _shouldInsertAd_: boolean }[] {
id: string;
createdAt?: string;
created_at?: string;
_shouldInsertAd_: boolean;
}[]
>, >,
required: true, required: true,
}, },
@ -57,8 +62,11 @@ export default defineComponent({
if ( if (
i !== props.items.length - 1 && i !== props.items.length - 1 &&
new Date(item.createdAt).getDate() !== new Date(item.createdAt || item.created_at!).getDate() !==
new Date(props.items[i + 1].createdAt).getDate() new Date(
props.items[i + 1].createdAt ||
props.items[i + 1].created_at!
).getDate()
) { ) {
const separator = h( const separator = h(
"div", "div",
@ -76,10 +84,15 @@ export default defineComponent({
h("i", { h("i", {
class: "ph-caret-up ph-bold ph-lg icon", class: "ph-caret-up ph-bold ph-lg icon",
}), }),
getDateText(item.createdAt), getDateText(
item.createdAt || item.created_at!
),
]), ]),
h("span", [ h("span", [
getDateText(props.items[i + 1].createdAt), getDateText(
props.items[i + 1].createdAt ||
props.items[i + 1].created_at!
),
h("i", { h("i", {
class: "ph-caret-down ph-bold ph-lg icon", class: "ph-caret-down ph-bold ph-lg icon",
}), }),

View File

@ -9,7 +9,7 @@
</div> </div>
<article> <article>
<header> <header>
<MkAvatar :user="post.user" class="avatar" /> <MagAvatarResolvingProxy :user="post.user" class="avatar" />
</header> </header>
<footer> <footer>
<span class="title">{{ post.title }}</span> <span class="title">{{ post.title }}</span>
@ -19,8 +19,6 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import {} from "vue";
import { userName } from "@/filters/user";
import ImgWithBlurhash from "@/components/MkImgWithBlurhash.vue"; import ImgWithBlurhash from "@/components/MkImgWithBlurhash.vue";
const props = defineProps<{ const props = defineProps<{

View File

@ -43,7 +43,7 @@
class="ph-fw ph-lg" class="ph-fw ph-lg"
:class="item.icon" :class="item.icon"
></i> ></i>
<MkAvatar <MagAvatarResolvingProxy
v-if="item.avatar" v-if="item.avatar"
:user="item.avatar" :user="item.avatar"
class="avatar" class="avatar"
@ -87,7 +87,7 @@
@mouseenter.passive="onItemMouseEnter(item)" @mouseenter.passive="onItemMouseEnter(item)"
@mouseleave.passive="onItemMouseLeave(item)" @mouseleave.passive="onItemMouseLeave(item)"
> >
<MkAvatar <MagAvatarResolvingProxy
:user="item.user" :user="item.user"
class="avatar" class="avatar"
disableLink disableLink
@ -149,7 +149,7 @@
class="ph-fw ph-lg" class="ph-fw ph-lg"
:class="item.icon" :class="item.icon"
></i> ></i>
<MkAvatar <MagAvatarResolvingProxy
v-if="item.avatar" v-if="item.avatar"
:user="item.avatar" :user="item.avatar"
class="avatar" class="avatar"
@ -184,20 +184,14 @@
<script lang="ts" setup> <script lang="ts" setup>
import { import {
computed,
menu,
defineAsyncComponent, defineAsyncComponent,
nextTick,
onBeforeUnmount, onBeforeUnmount,
onMounted, onMounted,
onUnmounted,
Ref,
ref, ref,
watch, watch,
} from "vue"; } from "vue";
import { focusPrev, focusNext } from "@/scripts/focus";
import FormSwitch from "@/components/form/switch.vue"; import FormSwitch from "@/components/form/switch.vue";
import { MenuItem, InnerMenuItem, MenuPending, MenuAction } from "@/types/menu"; import { InnerMenuItem, MenuAction, MenuItem, MenuPending } from "@/types/menu";
import * as os from "@/os"; import * as os from "@/os";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { FocusTrap } from "focus-trap-vue"; import { FocusTrap } from "focus-trap-vue";

View File

@ -1,6 +1,6 @@
<template> <template>
<div v-size="{ min: [350, 500] }" class="fefdfafb"> <div v-size="{ min: [350, 500] }" class="fefdfafb">
<MkAvatar class="avatar" :user="$i" disableLink /> <MagAvatarResolvingProxy class="avatar" :user="$i" disableLink />
<div class="main"> <div class="main">
<div class="header"> <div class="header">
<MkUserName :user="$i" /> <MkUserName :user="$i" />
@ -22,6 +22,7 @@
<script lang="ts" setup> <script lang="ts" setup>
import { preprocess } from "@/scripts/preprocess"; import { preprocess } from "@/scripts/preprocess";
import { $i } from "@/account";
const props = defineProps<{ const props = defineProps<{
text: string; text: string;

View File

@ -26,7 +26,7 @@
<XNoteResolvingProxy <XNoteResolvingProxy
:key="note._featuredId_ || note._prId_ || note.id" :key="note._featuredId_ || note._prId_ || note.id"
class="qtqtichx" class="qtqtichx"
:note="note.id" :note="noteIsMag(note) ? note : note.id"
/> />
</XList> </XList>
</div> </div>
@ -41,6 +41,7 @@ import MkPagination from "@/components/MkPagination.vue";
import XNoteResolvingProxy from "@/components/MagNoteResolvingProxy.vue"; import XNoteResolvingProxy from "@/components/MagNoteResolvingProxy.vue";
import XList from "@/components/MkDateSeparatedList.vue"; import XList from "@/components/MkDateSeparatedList.vue";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { noteIsMag } from "@/scripts-mag/mag-util";
const props = defineProps<{ const props = defineProps<{
pagination: Paging; pagination: Paging;

View File

@ -6,12 +6,12 @@
:class="notification.type" :class="notification.type"
> >
<div class="head"> <div class="head">
<MkAvatar <MagAvatarResolvingProxy
v-if="notification.type === 'pollEnded'" v-if="notification.type === 'pollEnded'"
class="icon" class="icon"
:user="notification.note.user" :user="notification.note.user"
/> />
<MkAvatar <MagAvatarResolvingProxy
v-else-if="notification.user" v-else-if="notification.user"
class="icon" class="icon"
:user="notification.user" :user="notification.user"
@ -187,7 +187,7 @@
:text="getNoteSummary(notification.note)" :text="getNoteSummary(notification.note)"
:plain="true" :plain="true"
:nowrap="!full" :nowrap="!full"
:custom-emojis="notification.note.emojis" :custom-emojis="notification.note?.emojis"
/> />
<i class="ph-quotes ph-fill ph-lg"></i> <i class="ph-quotes ph-fill ph-lg"></i>
</MkA> </MkA>

View File

@ -20,7 +20,10 @@
class="account _button" class="account _button"
@click="openAccountMenu" @click="openAccountMenu"
> >
<MkAvatar :user="postAccount ?? $i" class="avatar" /> <MagAvatarResolvingProxy
:user="postAccount ?? $i"
class="avatar"
/>
</button> </button>
<div class="right"> <div class="right">
<span <span

View File

@ -25,8 +25,8 @@ import MkPostForm from "@/components/MkPostForm.vue";
import { packed } from "magnetar-common"; import { packed } from "magnetar-common";
const props = defineProps<{ const props = defineProps<{
reply?: packed.PackNoteMaybeFull | misskey.entities.Note; reply?: packed.PackNoteMaybeFull;
renote?: packed.PackNoteMaybeFull | misskey.entities.Note; renote?: packed.PackNoteMaybeFull;
mention?: misskey.entities.User; mention?: misskey.entities.User;
specified?: misskey.entities.User; specified?: misskey.entities.User;
initialText?: string; initialText?: string;
@ -34,7 +34,7 @@ const props = defineProps<{
initialFiles?: misskey.entities.DriveFile[]; initialFiles?: misskey.entities.DriveFile[];
initialLocalOnly?: boolean; initialLocalOnly?: boolean;
initialVisibleUsers?: misskey.entities.User[]; initialVisibleUsers?: misskey.entities.User[];
initialNote?: packed.PackNoteMaybeFull | misskey.entities.Note; initialNote?: packed.PackNoteMaybeFull;
instant?: boolean; instant?: boolean;
fixed?: boolean; fixed?: boolean;
autofocus?: boolean; autofocus?: boolean;

View File

@ -21,7 +21,7 @@
</div> </div>
<div class="users"> <div class="users">
<div v-for="u in users" :key="u.id" class="user"> <div v-for="u in users" :key="u.id" class="user">
<MkAvatar class="avatar" :user="u" /> <MagAvatarResolvingProxy class="avatar" :user="u" />
<MkUserName class="name" :user="u" :nowrap="true" /> <MkUserName class="name" :user="u" :nowrap="true" />
</div> </div>
<div v-if="users.length > 10" class="omitted"> <div v-if="users.length > 10" class="omitted">
@ -33,7 +33,6 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import {} from "vue";
import MkTooltip from "./MkTooltip.vue"; import MkTooltip from "./MkTooltip.vue";
import { magIsUnicodeEmoji, magReactionToLegacy } from "@/scripts-mag/mag-util"; import { magIsUnicodeEmoji, magReactionToLegacy } from "@/scripts-mag/mag-util";
import { types } from "magnetar-common"; import { types } from "magnetar-common";

View File

@ -18,7 +18,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { ref, computed, provide, onUnmounted } from "vue"; import { onUnmounted } from "vue";
import XNotes from "@/components/MkNotes.vue"; import XNotes from "@/components/MkNotes.vue";
import MkInfo from "@/components/MkInfo.vue"; import MkInfo from "@/components/MkInfo.vue";
import * as os from "@/os"; import * as os from "@/os";
@ -27,6 +27,7 @@ import * as sound from "@/scripts/sound";
import { $i } from "@/account"; import { $i } from "@/account";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { defaultStore } from "@/store"; import { defaultStore } from "@/store";
import { endpoints } from "magnetar-common";
const props = defineProps<{ const props = defineProps<{
src: string; src: string;
@ -42,14 +43,22 @@ const emit = defineEmits<{
const tlComponent: InstanceType<typeof XNotes> = $ref(); const tlComponent: InstanceType<typeof XNotes> = $ref();
const prepend = (note) => { const prepend = (note: string) => {
tlComponent.pagingComponent?.prepend(note); os.magApi(
endpoints.GetNoteById,
{ context: true, attachments: true },
{
id: note,
}
).then((n) => {
tlComponent.pagingComponent?.prepend(n);
emit("note"); emit("note");
if (props.sound) { if (props.sound) {
sound.play($i && note.userId === $i.id ? "noteMy" : "note"); sound.play($i && n.user.id === $i.id ? "noteMy" : "note");
} }
});
}; };
const onUserAdded = () => { const onUserAdded = () => {

View File

@ -7,7 +7,7 @@
]" ]"
:to="userPage(user)" :to="userPage(user)"
> >
<MkAvatar <MagAvatarResolvingProxy
class="avatar" class="avatar"
:user="user" :user="user"
:disable-link="true" :disable-link="true"

View File

@ -6,7 +6,7 @@
user.bannerUrl ? `background-image: url(${user.bannerUrl})` : '' user.bannerUrl ? `background-image: url(${user.bannerUrl})` : ''
" "
></div> ></div>
<MkAvatar <MagAvatarResolvingProxy
class="avatar" class="avatar"
:user="user" :user="user"
:disable-preview="true" :disable-preview="true"
@ -57,6 +57,7 @@ import MkFollowButton from "@/components/MkFollowButton.vue";
import MkNumber from "@/components/MkNumber.vue"; import MkNumber from "@/components/MkNumber.vue";
import { userPage } from "@/filters/user"; import { userPage } from "@/filters/user";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { $i } from "@/account";
defineProps<{ defineProps<{
user: misskey.entities.UserDetailed; user: misskey.entities.UserDetailed;

View File

@ -42,7 +42,7 @@
@click="selected = user" @click="selected = user"
@dblclick="ok()" @dblclick="ok()"
> >
<MkAvatar <MagAvatarResolvingProxy
:user="user" :user="user"
class="avatar" class="avatar"
:show-indicator="true" :show-indicator="true"
@ -70,7 +70,7 @@
@click="selected = user" @click="selected = user"
@dblclick="ok()" @dblclick="ok()"
> >
<MkAvatar <MagAvatar
:user="user" :user="user"
class="avatar" class="avatar"
:show-indicator="true" :show-indicator="true"
@ -88,7 +88,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { nextTick, onMounted } from "vue"; import { onMounted } from "vue";
import * as misskey from "calckey-js"; import * as misskey from "calckey-js";
import MkInput from "@/components/form/input.vue"; import MkInput from "@/components/form/input.vue";
import FormSplit from "@/components/form/split.vue"; import FormSplit from "@/components/form/split.vue";

View File

@ -7,7 +7,7 @@
> >
<div class="beaffaef"> <div class="beaffaef">
<div v-for="u in users" :key="u.id" class="user"> <div v-for="u in users" :key="u.id" class="user">
<MkAvatar class="avatar" :user="u" disableLink /> <MagAvatarResolvingProxy class="avatar" :user="u" disableLink />
<MkUserName class="name" :user="u" :nowrap="true" /> <MkUserName class="name" :user="u" :nowrap="true" />
</div> </div>
<div v-if="users.length < count" class="omitted"> <div v-if="users.length < count" class="omitted">
@ -18,7 +18,6 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import {} from "vue";
import MkTooltip from "./MkTooltip.vue"; import MkTooltip from "./MkTooltip.vue";
const props = defineProps<{ const props = defineProps<{

View File

@ -4,13 +4,7 @@
v-user-preview="disablePreview ? undefined : user.id" v-user-preview="disablePreview ? undefined : user.id"
class="eiwwqkts _noSelect" class="eiwwqkts _noSelect"
:class="{ :class="{
cat: cat: props.user.avatar_decoration === 'CatEars' || false,
magTransMap(
props.user,
'avatar_decoration',
'isCat',
(a) => a === 'CatEars'
) || false,
square: $store.state.squareAvatars, square: $store.state.squareAvatars,
}" }"
:style="{ color }" :style="{ color }"
@ -24,13 +18,7 @@
v-user-preview="disablePreview ? undefined : user.id" v-user-preview="disablePreview ? undefined : user.id"
class="eiwwqkts _noSelect" class="eiwwqkts _noSelect"
:class="{ :class="{
cat: cat: props.user.avatar_decoration === 'CatEars' || false,
magTransMap(
props.user,
'avatar_decoration',
'isCat',
(d) => d === 'CatEars'
) || false,
square: $store.state.squareAvatars, square: $store.state.squareAvatars,
}" }"
:style="{ color }" :style="{ color }"
@ -45,17 +33,15 @@
<script lang="ts" setup> <script lang="ts" setup>
import { watch } from "vue"; import { watch } from "vue";
import * as misskey from "calckey-js";
import { getStaticImageUrl } from "@/scripts/get-static-image-url"; import { getStaticImageUrl } from "@/scripts/get-static-image-url";
import { extractAvgColorFromBlurhash } from "@/scripts/extract-avg-color-from-blurhash"; import { extractAvgColorFromBlurhash } from "@/scripts/extract-avg-color-from-blurhash";
import { acct, userPage } from "@/filters/user"; import { acct, userPage } from "@/filters/user";
import { defaultStore } from "@/store"; import { defaultStore } from "@/store";
import { packed } from "magnetar-common"; import { packed } from "magnetar-common";
import { magTransMap, magTransProperty } from "@/scripts-mag/mag-util";
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
user: packed.PackUserBase | misskey.entities.User; user: packed.PackUserBase;
target?: string | null; target?: string | null;
disableLink?: boolean; disableLink?: boolean;
disablePreview?: boolean; disablePreview?: boolean;
@ -73,10 +59,8 @@ const emit = defineEmits<{
const url = $computed(() => const url = $computed(() =>
defaultStore.state.disableShowingAnimatedImages defaultStore.state.disableShowingAnimatedImages
? getStaticImageUrl( ? getStaticImageUrl(props.user.avatar_url)
magTransProperty(props.user, "avatar_url", "avatarUrl") : props.user.avatar_url
)
: magTransProperty(props.user, "avatar_url", "avatarUrl")
); );
function onClick(ev: MouseEvent) { function onClick(ev: MouseEvent) {
@ -86,11 +70,9 @@ function onClick(ev: MouseEvent) {
let color = $ref<string>(); let color = $ref<string>();
watch( watch(
() => magTransProperty(props.user, "avatar_blurhash", "avatarBlurhash"), () => props.user.avatar_blurhash,
() => { () => {
color = extractAvgColorFromBlurhash( color = extractAvgColorFromBlurhash(props.user.avatar_blurhash);
magTransProperty(props.user, "avatar_blurhash", "avatarBlurhash")
);
}, },
{ {
immediate: true, immediate: true,

View File

@ -0,0 +1,43 @@
<template>
<MagAvatar v-if="userResolved" :user="userResolved" />
</template>
<script lang="ts" setup>
import { ref, watch } from "vue";
import { userIsMag } from "@/scripts-mag/mag-util";
import { endpoints, packed } from "magnetar-common";
import type * as Misskey from "calckey-js";
import * as os from "@/os";
const props = withDefaults(
defineProps<{
user: packed.PackUserBase | Misskey.entities.User;
target?: string | null;
disableLink?: boolean;
disablePreview?: boolean;
}>(),
{
target: null,
disableLink: false,
disablePreview: false,
}
);
const userResolved = ref<packed.PackUserBase | null>(null);
watch(
() => props.user,
async (val) => {
if (userIsMag(val)) {
userResolved.value = val;
}
userResolved.value = await os.magApi(
endpoints.GetUserById,
{},
{ user_id: val.id }
);
},
{ immediate: true }
);
</script>

View File

@ -18,7 +18,7 @@
> >
<i class="ph-caret-left ph-bold ph-lg"></i> <i class="ph-caret-left ph-bold ph-lg"></i>
</button> </button>
<MkAvatar <MagAvatarResolvingProxy
v-if="narrow && props.displayMyAvatar && $i" v-if="narrow && props.displayMyAvatar && $i"
class="avatar button" class="avatar button"
:user="$i" :user="$i"
@ -32,7 +32,7 @@
class="titleContainer" class="titleContainer"
@click="showTabsPopup" @click="showTabsPopup"
> >
<MkAvatar <MagAvatar
v-if="metadata.avatar" v-if="metadata.avatar"
class="avatar" class="avatar"
:user="metadata.avatar" :user="metadata.avatar"

View File

@ -1,8 +1,5 @@
import * as Misskey from "calckey-js";
import { packed } from "magnetar-common"; import { packed } from "magnetar-common";
export const notePage = (note: { export const notePage = (note: { id: packed.PackNoteBase["id"] }) => {
id: packed.PackNoteBase["id"] | Misskey.entities.Note["id"];
}) => {
return `/notes/${note.id}`; return `/notes/${note.id}`;
}; };

View File

@ -46,7 +46,8 @@ import { getAccountFromId } from "@/scripts/get-account-from-id";
import Mfm from "./components/global/MkMisskeyFlavoredMarkdown.vue"; import Mfm from "./components/global/MkMisskeyFlavoredMarkdown.vue";
import MkA from "./components/global/MkA.vue"; import MkA from "./components/global/MkA.vue";
import MkAcct from "./components/global/MkAcct.vue"; import MkAcct from "./components/global/MkAcct.vue";
import MkAvatar from "./components/global/MkAvatar.vue"; import MagAvatar from "./components/global/MagAvatar.vue";
import MagAvatarResolvingProxy from "./components/global/MagAvatarResolvingProxy.vue";
import MagEmoji from "./components/global/MagEmoji.vue"; import MagEmoji from "./components/global/MagEmoji.vue";
import MkUserName from "./components/global/MkUserName.vue"; import MkUserName from "./components/global/MkUserName.vue";
import MkEllipsis from "./components/global/MkEllipsis.vue"; import MkEllipsis from "./components/global/MkEllipsis.vue";
@ -67,7 +68,7 @@ function globalComponents(app: App) {
app.component("Mfm", Mfm); app.component("Mfm", Mfm);
app.component("MkA", MkA); app.component("MkA", MkA);
app.component("MkAcct", MkAcct); app.component("MkAcct", MkAcct);
app.component("MkAvatar", MkAvatar); app.component("MagAvatar", MagAvatar);
app.component("MagEmoji", MagEmoji); app.component("MagEmoji", MagEmoji);
app.component("MkUserName", MkUserName); app.component("MkUserName", MkUserName);
app.component("MkEllipsis", MkEllipsis); app.component("MkEllipsis", MkEllipsis);
@ -79,6 +80,7 @@ function globalComponents(app: App) {
app.component("MkPageHeader", MkPageHeader); app.component("MkPageHeader", MkPageHeader);
app.component("MkSpacer", MkSpacer); app.component("MkSpacer", MkSpacer);
app.component("MkStickyContainer", MkStickyContainer); app.component("MkStickyContainer", MkStickyContainer);
app.component("MagAvatarResolvingProxy", MagAvatarResolvingProxy);
} }
declare module "@vue/runtime-core" { declare module "@vue/runtime-core" {
@ -88,7 +90,7 @@ declare module "@vue/runtime-core" {
Mfm: typeof Mfm; Mfm: typeof Mfm;
MkA: typeof MkA; MkA: typeof MkA;
MkAcct: typeof MkAcct; MkAcct: typeof MkAcct;
MkAvatar: typeof MkAvatar; MagAvatar: typeof MagAvatar;
MagEmoji: typeof MagEmoji; MagEmoji: typeof MagEmoji;
MkUserName: typeof MkUserName; MkUserName: typeof MkUserName;
MkEllipsis: typeof MkEllipsis; MkEllipsis: typeof MkEllipsis;
@ -100,6 +102,7 @@ declare module "@vue/runtime-core" {
MkPageHeader: typeof MkPageHeader; MkPageHeader: typeof MkPageHeader;
MkSpacer: typeof MkSpacer; MkSpacer: typeof MkSpacer;
MkStickyContainer: typeof MkStickyContainer; MkStickyContainer: typeof MkStickyContainer;
MagAvatarResolvingProxy: typeof MagAvatarResolvingProxy;
} }
} }

View File

@ -66,6 +66,7 @@ import {
definePageMetadata, definePageMetadata,
provideMetadataReceiver, provideMetadataReceiver,
} from "@/scripts/page-metadata"; } from "@/scripts/page-metadata";
import { endpoints } from "magnetar-common";
const isEmpty = (x: string | null) => x == null || x === ""; const isEmpty = (x: string | null) => x == null || x === "";
const el = ref<HTMLElement | null>(null); const el = ref<HTMLElement | null>(null);
@ -332,12 +333,18 @@ async function lookupNote() {
}); });
if (canceled) return; if (canceled) return;
os.api( if (q?.startsWith("http://") || q?.startsWith("https://")) {
"notes/show", const obj = await os.api("ap/show", {
q.startsWith("http://") || q.startsWith("https://") uri: q,
? { url: q.trim() } });
: { noteId: q.trim() } if (obj.type === "Note") {
) os.pageWindow(`/notes/${obj.object.id}`);
}
return;
}
os.magApi(endpoints.GetNoteById, {}, { id: q.trim() })
.then((note) => { .then((note) => {
os.pageWindow(`/notes/${note.id}`); os.pageWindow(`/notes/${note.id}`);
}) })

View File

@ -12,7 +12,7 @@
class="user" class="user"
:to="`/user-info/${user.id}`" :to="`/user-info/${user.id}`"
> >
<MkAvatar <MagAvatarResolvingProxy
:user="user" :user="user"
class="avatar" class="avatar"
indicator indicator
@ -25,10 +25,8 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { onMounted, onUnmounted, ref } from "vue"; import { onMounted } from "vue";
import * as os from "@/os"; import * as os from "@/os";
import number from "@/filters/number";
import { i18n } from "@/i18n";
let moderators: any = $ref(null); let moderators: any = $ref(null);
let fetching = $ref(true); let fetching = $ref(true);

View File

@ -1,6 +1,6 @@
<template> <template>
<MkA :class="[$style.root]" :to="`/user-info/${user.id}`"> <MkA :class="[$style.root]" :to="`/user-info/${user.id}`">
<MkAvatar <MagAvatarResolvingProxy
class="avatar" class="avatar"
:user="user" :user="user"
:disable-link="true" :disable-link="true"

View File

@ -12,7 +12,7 @@
/> />
</div> </div>
<div class="user"> <div class="user">
<MkAvatar <MagAvatarResolvingProxy
:user="clip.user" :user="clip.user"
class="avatar" class="avatar"
:show-indicator="true" :show-indicator="true"
@ -28,7 +28,7 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, watch, provide } from "vue"; import { computed, provide, watch } from "vue";
import type * as misskey from "calckey-js"; import type * as misskey from "calckey-js";
import XNotes from "@/components/MkNotes.vue"; import XNotes from "@/components/MkNotes.vue";
import { $i } from "@/account"; import { $i } from "@/account";

View File

@ -37,11 +37,5 @@ const paginationForRemote = {
}, },
}; };
// const paginationForRemote = {
// endpoint: 'notes/polls/recommendation' as const,
// limit: 10,
// offsetMode: true,
// };
let tab = $ref("local"); let tab = $ref("local");
</script> </script>

View File

@ -23,7 +23,7 @@
:key="req.id" :key="req.id"
class="user _panel" class="user _panel"
> >
<MkAvatar <MagAvatarResolvingProxy
class="avatar" class="avatar"
:user="req.follower" :user="req.follower"
:show-indicator="true" :show-indicator="true"

View File

@ -92,7 +92,10 @@
</div> </div>
</div> </div>
<div class="user"> <div class="user">
<MkAvatar :user="post.user" class="avatar" /> <MagAvatarResolvingProxy
:user="post.user"
class="avatar"
/>
<div class="name"> <div class="name">
<MkUserName <MkUserName
:user="post.user" :user="post.user"
@ -157,6 +160,7 @@ import { useRouter } from "@/router";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { definePageMetadata } from "@/scripts/page-metadata"; import { definePageMetadata } from "@/scripts/page-metadata";
import { shareAvailable } from "@/scripts/share-available"; import { shareAvailable } from "@/scripts/share-available";
import { $i } from "@/account";
const router = useRouter(); const router = useRouter();

View File

@ -10,7 +10,7 @@
:key="user.id" :key="user.id"
class="user _panel" class="user _panel"
> >
<MkAvatar <MagAvatarResolvingProxy
:user="user" :user="user"
class="avatar" class="avatar"
:show-indicator="true" :show-indicator="true"

View File

@ -37,7 +37,7 @@
:key="user.id" :key="user.id"
class="user _panel" class="user _panel"
> >
<MkAvatar <MagAvatarResolvingProxy
:user="user" :user="user"
class="avatar" class="avatar"
:show-indicator="true" :show-indicator="true"

View File

@ -141,7 +141,10 @@
</button> </button>
</div> </div>
<div class="user"> <div class="user">
<MkAvatar :user="page.user" class="avatar" /> <MagAvatarResolvingProxy
:user="page.user"
class="avatar"
/>
<div class="name"> <div class="name">
<MkUserName <MkUserName
:user="page.user" :user="page.user"
@ -213,6 +216,7 @@ import { i18n } from "@/i18n";
import copyToClipboard from "@/scripts/copy-to-clipboard"; import copyToClipboard from "@/scripts/copy-to-clipboard";
import { definePageMetadata } from "@/scripts/page-metadata"; import { definePageMetadata } from "@/scripts/page-metadata";
import { shareAvailable } from "@/scripts/share-available"; import { shareAvailable } from "@/scripts/share-available";
import { $i } from "@/account";
const props = defineProps<{ const props = defineProps<{
pageName: string; pageName: string;

View File

@ -13,7 +13,11 @@
@click="menu(account, $event)" @click="menu(account, $event)"
> >
<div class="avatar"> <div class="avatar">
<MkAvatar :user="account" class="avatar" disableLink /> <MagAvatarResolvingProxy
:user="account"
class="avatar"
disableLink
/>
</div> </div>
<div class="body"> <div class="body">
<div class="name"> <div class="name">
@ -34,11 +38,11 @@ import FormSuspense from "@/components/form/suspense.vue";
import FormButton from "@/components/MkButton.vue"; import FormButton from "@/components/MkButton.vue";
import * as os from "@/os"; import * as os from "@/os";
import { import {
getAccounts,
addAccount as addAccounts,
removeAccount as _removeAccount,
login,
$i, $i,
addAccount as addAccounts,
getAccounts,
login,
removeAccount as _removeAccount,
} from "@/account"; } from "@/account";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { definePageMetadata } from "@/scripts/page-metadata"; import { definePageMetadata } from "@/scripts/page-metadata";

View File

@ -11,7 +11,7 @@
}" }"
> >
<div class="avatar"> <div class="avatar">
<MkAvatar <MagAvatarResolvingProxy
class="avatar" class="avatar"
:user="$i" :user="$i"
:disable-link="true" :disable-link="true"

View File

@ -32,16 +32,16 @@
<script lang="ts" setup> <script lang="ts" setup>
// SPECIFICATION: https://misskey-hub.net/docs/features/share-form.html // SPECIFICATION: https://misskey-hub.net/docs/features/share-form.html
import {} from "vue"; import * as Misskey from "calckey-js";
import { noteVisibilities } from "calckey-js"; import { noteVisibilities } from "calckey-js";
import * as Acct from "calckey-js/built/acct"; import * as Acct from "calckey-js/built/acct";
import * as Misskey from "calckey-js";
import MkButton from "@/components/MkButton.vue"; import MkButton from "@/components/MkButton.vue";
import XPostForm from "@/components/MkPostForm.vue"; import XPostForm from "@/components/MkPostForm.vue";
import * as os from "@/os"; import * as os from "@/os";
import { mainRouter } from "@/router"; import { mainRouter } from "@/router";
import { definePageMetadata } from "@/scripts/page-metadata"; import { definePageMetadata } from "@/scripts/page-metadata";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { endpoints, packed } from "magnetar-common";
const urlParams = new URLSearchParams(window.location.search); const urlParams = new URLSearchParams(window.location.search);
const localOnlyQuery = urlParams.get("localOnly"); const localOnlyQuery = urlParams.get("localOnly");
@ -51,9 +51,9 @@ let state = $ref("fetching" as "fetching" | "writing" | "posted");
let title = $ref(urlParams.get("title")); let title = $ref(urlParams.get("title"));
const text = urlParams.get("text"); const text = urlParams.get("text");
const url = urlParams.get("url"); const url = urlParams.get("url");
let initialText = $ref(null as string | null); let initialText = $ref<string | null>(null);
let reply = $ref(null as Misskey.entities.Note | null); let reply = $ref<packed.PackNoteMaybeFull | null>(null);
let renote = $ref(null as Misskey.entities.Note | null); let renote = $ref<packed.PackNoteMaybeFull | null>(null);
let visibility = $ref( let visibility = $ref(
noteVisibilities.includes(visibilityQuery) ? visibilityQuery : null noteVisibilities.includes(visibilityQuery) ? visibilityQuery : null
); );
@ -114,15 +114,21 @@ async function init() {
const replyId = urlParams.get("replyId"); const replyId = urlParams.get("replyId");
const replyUri = urlParams.get("replyUri"); const replyUri = urlParams.get("replyUri");
if (replyId) { if (replyId) {
reply = await os.api("notes/show", { reply = await os.magApi(
noteId: replyId, endpoints.GetNoteById,
}); { attachments: true, context: true },
{ id: replyId }
);
} else if (replyUri) { } else if (replyUri) {
const obj = await os.api("ap/show", { const obj = await os.api("ap/show", {
uri: replyUri, uri: replyUri,
}); });
if (obj.type === "Note") { if (obj.type === "Note") {
reply = obj.object; reply = await os.magApi(
endpoints.GetNoteById,
{ attachments: true, context: true },
{ id: obj.object.id }
);
} }
} }
//#endregion //#endregion
@ -131,15 +137,21 @@ async function init() {
const renoteId = urlParams.get("renoteId"); const renoteId = urlParams.get("renoteId");
const renoteUri = urlParams.get("renoteUri"); const renoteUri = urlParams.get("renoteUri");
if (renoteId) { if (renoteId) {
renote = await os.api("notes/show", { renote = await os.magApi(
noteId: renoteId, endpoints.GetNoteById,
}); { attachments: true, context: true },
{ id: renoteId }
);
} else if (renoteUri) { } else if (renoteUri) {
const obj = await os.api("ap/show", { const obj = await os.api("ap/show", {
uri: renoteUri, uri: renoteUri,
}); });
if (obj.type === "Note") { if (obj.type === "Note") {
renote = obj.object; renote = await os.magApi(
endpoints.GetNoteById,
{ attachments: true, context: true },
{ id: obj.object.id }
);
} }
} }
//#endregion //#endregion

View File

@ -10,7 +10,7 @@
<FormSuspense :p="init"> <FormSuspense :p="init">
<div v-if="tab === 'overview'" class="_formRoot"> <div v-if="tab === 'overview'" class="_formRoot">
<div class="_formBlock aeakzknw"> <div class="_formBlock aeakzknw">
<MkAvatar <MagAvatarResolvingProxy
class="avatar" class="avatar"
:user="user" :user="user"
:show-indicator="true" :show-indicator="true"
@ -349,7 +349,6 @@ import FormLink from "@/components/form/link.vue";
import FormSection from "@/components/form/section.vue"; import FormSection from "@/components/form/section.vue";
import FormButton from "@/components/MkButton.vue"; import FormButton from "@/components/MkButton.vue";
import FormInput from "@/components/form/input.vue"; import FormInput from "@/components/form/input.vue";
import FormSplit from "@/components/form/split.vue";
import FormFolder from "@/components/form/folder.vue"; import FormFolder from "@/components/form/folder.vue";
import MkKeyValue from "@/components/MkKeyValue.vue"; import MkKeyValue from "@/components/MkKeyValue.vue";
import MkSelect from "@/components/form/select.vue"; import MkSelect from "@/components/form/select.vue";
@ -357,13 +356,11 @@ import FormSuspense from "@/components/form/suspense.vue";
import MkFileListForAdmin from "@/components/MkFileListForAdmin.vue"; import MkFileListForAdmin from "@/components/MkFileListForAdmin.vue";
import MkInfo from "@/components/MkInfo.vue"; import MkInfo from "@/components/MkInfo.vue";
import * as os from "@/os"; import * as os from "@/os";
import number from "@/filters/number";
import bytes from "@/filters/bytes";
import { url } from "@/config"; import { url } from "@/config";
import { userPage, acct } from "@/filters/user"; import { acct, userPage } from "@/filters/user";
import { definePageMetadata } from "@/scripts/page-metadata"; import { definePageMetadata } from "@/scripts/page-metadata";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { iAmAdmin, iAmModerator } from "@/account"; import { $i, iAmAdmin, iAmModerator } from "@/account";
import { instance } from "@/instance"; import { instance } from "@/instance";
const props = defineProps<{ const props = defineProps<{

View File

@ -119,7 +119,7 @@
</div> </div>
</div> </div>
</div> </div>
<MkAvatar <MagAvatar
class="avatar" class="avatar"
:user="user" :user="user"
:disable-preview="true" :disable-preview="true"
@ -392,7 +392,6 @@ import { i18n } from "@/i18n";
import { $i } from "@/account"; import { $i } from "@/account";
import MkFollowApproveButton from "@/components/MkFollowApproveButton.vue"; import MkFollowApproveButton from "@/components/MkFollowApproveButton.vue";
import MkUserName from "@/components/global/MkUserName.vue"; import MkUserName from "@/components/global/MkUserName.vue";
import MkAvatar from "@/components/global/MkAvatar.vue";
import Mfm from "@/components/mfm.vue"; import Mfm from "@/components/mfm.vue";
import MkTime from "@/components/global/MkTime.vue"; import MkTime from "@/components/global/MkTime.vue";
import MkA from "@/components/global/MkA.vue"; import MkA from "@/components/global/MkA.vue";

View File

@ -13,14 +13,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed, ref } from "vue"; import { computed, ref } from "vue";
import * as misskey from "calckey-js";
import XNotes from "@/components/MkNotes.vue"; import XNotes from "@/components/MkNotes.vue";
import MkTab from "@/components/MkTab.vue"; import MkTab from "@/components/MkTab.vue";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";
import { packed } from "magnetar-common"; import { packed } from "magnetar-common";
const props = defineProps<{ const props = defineProps<{
user: packed.PackUserBase | misskey.entities.UserDetailed; user: packed.PackUserBase;
}>(); }>();
const include = ref<string | null>(null); const include = ref<string | null>(null);

View File

@ -8,7 +8,7 @@
class="item _panel _gap afdcfbfb" class="item _panel _gap afdcfbfb"
> >
<div class="header"> <div class="header">
<MkAvatar class="avatar" :user="user" /> <MagAvatar class="avatar" :user="user" />
<MkReactionIcon <MkReactionIcon
class="reaction" class="reaction"
:reaction="item.type" :reaction="item.type"
@ -25,13 +25,13 @@
<script lang="ts" setup> <script lang="ts" setup>
import { computed } from "vue"; import { computed } from "vue";
import * as misskey from "calckey-js";
import MkPagination from "@/components/MkPagination.vue"; import MkPagination from "@/components/MkPagination.vue";
import XNoteResolvingProxy from "@/components/MagNoteResolvingProxy.vue"; import XNoteResolvingProxy from "@/components/MagNoteResolvingProxy.vue";
import MkReactionIcon from "@/components/MkReactionIcon.vue"; import MkReactionIcon from "@/components/MkReactionIcon.vue";
import { packed } from "magnetar-common";
const props = defineProps<{ const props = defineProps<{
user: misskey.entities.User; user: packed.PackUserBase;
}>(); }>();
const pagination = { const pagination = {

View File

@ -131,6 +131,12 @@ export function magReactionSelf(
return null; return null;
} }
export function userIsMag(
user: packed.PackUserBase | Misskey.entities.User
): user is packed.PackUserBase {
return "created_at" in user;
}
export function noteIsMag( export function noteIsMag(
note: packed.PackNoteMaybeFull | Misskey.entities.Note note: packed.PackNoteMaybeFull | Misskey.entities.Note
): note is packed.PackNoteMaybeFull { ): note is packed.PackNoteMaybeFull {

View File

@ -1,6 +1,4 @@
import { packed } from "magnetar-common"; import { packed } from "magnetar-common";
import * as Misskey from "calckey-js";
import { magTransMap, magTransProperty } from "@/scripts-mag/mag-util";
export type Muted = { export type Muted = {
muted: boolean; muted: boolean;
@ -11,13 +9,12 @@ export type Muted = {
export type NotMuted = { muted: false; matched: string[] }; export type NotMuted = { muted: false; matched: string[] };
function checkWordMute( function checkWordMute(
note: packed.PackNoteMaybeFull | Misskey.entities.Note, note: packed.PackNoteMaybeFull,
mutedWords: Array<string | string[]> mutedWords: Array<string | string[]>
): Muted { ): Muted {
let text = `${note.cw ?? ""} ${note.text ?? ""}`; let text = `${note.cw ?? ""} ${note.text ?? ""}`;
const attachments = magTransProperty(note, "attachments", "files"); if (note.attachments)
if (attachments) text += ` ${note.attachments?.map((f) => f.comment ?? "")?.join(" ")}`;
text += ` ${attachments.map((f) => f.comment ?? "").join(" ")}`;
text = text.trim(); text = text.trim();
let result: Muted | NotMuted = { muted: false, matched: [] }; let result: Muted | NotMuted = { muted: false, matched: [] };
@ -64,12 +61,12 @@ function checkWordMute(
} }
export function getWordSoftMute( export function getWordSoftMute(
note: packed.PackNoteMaybeFull | Misskey.entities.Note, note: packed.PackNoteMaybeFull,
me: Record<string, any> | null | undefined, me: Record<string, any> | null | undefined,
mutedWords: Array<string | string[]> mutedWords: Array<string | string[]>
): Muted { ): Muted {
// 自分自身 // 自分自身
if (me && magTransMap(note, "user", "userId", (u) => u.id) === me.id) { if (me && note.user.id === me.id) {
return { muted: false, matched: [] }; return { muted: false, matched: [] };
} }
@ -80,18 +77,16 @@ export function getWordSoftMute(
return noteMuted; return noteMuted;
} }
const renote = magTransProperty(note, "renoted_note", "renote"); if (note.renoted_note) {
if (renote) { let renoteMuted = checkWordMute(note.renoted_note, mutedWords);
let renoteMuted = checkWordMute(renote, mutedWords);
if (renoteMuted.muted) { if (renoteMuted.muted) {
renoteMuted.what = note.text == null ? "renote" : "quote"; renoteMuted.what = note.text == null ? "renote" : "quote";
return renoteMuted; return renoteMuted;
} }
} }
const reply = magTransProperty(note, "parent_note", "reply"); if (note.parent_note) {
if (reply) { let replyMuted = checkWordMute(note.parent_note, mutedWords);
let replyMuted = checkWordMute(reply, mutedWords);
if (replyMuted.muted) { if (replyMuted.muted) {
replyMuted.what = "reply"; replyMuted.what = "reply";
return replyMuted; return replyMuted;

View File

@ -2,13 +2,13 @@ import * as Acct from "calckey-js/built/acct";
import { host as localHost } from "@/config"; import { host as localHost } from "@/config";
export async function genSearchQuery(v: any, q: string) { export async function genSearchQuery(v: any, q: string) {
let host: string; let host: string | null;
let userId: string; let userId: string;
if (q.split(" ").some((x) => x.startsWith("@"))) { if (q.split(" ").some((x) => x.startsWith("@"))) {
for (const at of q for (const at of q
.split(" ") .split(" ")
.filter((x) => x.startsWith("@")) .filter((x) => x.startsWith("@"))
.map((x) => x.substr(1))) { .map((x) => x.substring(1))) {
if (at.includes(".")) { if (at.includes(".")) {
if (at === localHost || at === ".") { if (at === localHost || at === ".") {
host = null; host = null;

View File

@ -1,14 +1,10 @@
import * as misskey from "calckey-js";
import { packed } from "magnetar-common"; import { packed } from "magnetar-common";
import { magTransProperty } from "@/scripts-mag/mag-util";
/** /**
* 稿 * 稿
* @param {*} note (packされた)稿 * @param {*} note (packされた)稿
*/ */
export const getNoteSummary = ( export const getNoteSummary = (note: packed.PackNoteMaybeFull): string => {
note: packed.PackNoteMaybeFull | misskey.entities.Note
): string => {
/* /*
if (note.deletedAt) { if (note.deletedAt) {
return `(${i18n.ts.deletedNote})`; return `(${i18n.ts.deletedNote})`;
@ -25,9 +21,8 @@ export const getNoteSummary = (
} }
// ファイルが添付されているとき // ファイルが添付されているとき
const files = magTransProperty(note, "attachments", "files"); if ((note.attachments || []).length !== 0) {
if ((files || []).length !== 0) { const len = note.attachments?.length;
const len = files?.length;
summary += ` 📎${len !== 1 ? ` (${len})` : ""}`; summary += ` 📎${len !== 1 ? ` (${len})` : ""}`;
} }

View File

@ -8,7 +8,7 @@ export async function lookupUser() {
}); });
if (canceled) return; if (canceled) return;
const show = (user) => { const show = (user: { id: any }) => {
os.pageWindow(`/user-info/${user.id}`); os.pageWindow(`/user-info/${user.id}`);
}; };
@ -25,12 +25,10 @@ export async function lookupUser() {
_notFound = true; _notFound = true;
} }
}; };
usernamePromise.then(show).catch((err) => {
if (err.code === "NO_SUCH_USER") { Promise.any([usernamePromise, idPromise])
notFound(); .then(show)
} .catch(() => {
});
idPromise.then(show).catch((err) => {
notFound(); notFound();
}); });
} }

View File

@ -1,4 +1,3 @@
import * as misskey from "calckey-js";
import { import {
ComputedRef, ComputedRef,
inject, inject,
@ -18,8 +17,8 @@ export type PageMetadata = {
title: string; title: string;
subtitle?: string; subtitle?: string;
icon?: string | null; icon?: string | null;
avatar?: packed.PackUserBase | misskey.entities.User | null; avatar?: packed.PackUserBase | null;
userName?: packed.PackUserBase | misskey.entities.User | null; userName?: packed.PackUserBase | null;
bg?: string; bg?: string;
}; };

View File

@ -15,7 +15,7 @@
class="item _button account" class="item _button account"
@click="openAccountMenu" @click="openAccountMenu"
> >
<MkAvatar <MagAvatarResolvingProxy
:user="$i" :user="$i"
class="icon" class="icon"
disableLink disableLink
@ -118,17 +118,10 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { import { computed, defineAsyncComponent, toRef } from "vue";
computed,
defineAsyncComponent,
defineComponent,
ref,
toRef,
watch,
} from "vue";
import * as os from "@/os"; import * as os from "@/os";
import { navbarItemDef } from "@/navbar"; import { navbarItemDef } from "@/navbar";
import { openAccountMenu as openAccountMenu_ } from "@/account"; import { $i, openAccountMenu as openAccountMenu_ } from "@/account";
import { openHelpMenu_ } from "@/scripts/helpMenu"; import { openHelpMenu_ } from "@/scripts/helpMenu";
import { defaultStore } from "@/store"; import { defaultStore } from "@/store";
import { i18n } from "@/i18n"; import { i18n } from "@/i18n";

View File

@ -15,7 +15,7 @@
class="item _button account" class="item _button account"
@click="openAccountMenu" @click="openAccountMenu"
> >
<MkAvatar <MagAvatarResolvingProxy
:user="$i" :user="$i"
class="icon" class="icon"
disableLink disableLink
@ -133,12 +133,6 @@
> >
<i class="help icon ph-info ph-bold ph-xl ph-fw"></i> <i class="help icon ph-info ph-bold ph-xl ph-fw"></i>
</button> </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"/>
</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"/>
</button> -->
</div> </div>
</div> </div>
</header> </header>

View File

@ -10,7 +10,7 @@
<span v-for="note in notes" :key="note.id" class="item"> <span v-for="note in notes" :key="note.id" class="item">
<img <img
class="avatar" class="avatar"
:src="note.user.avatarUrl" :src="note.user.avatar_url"
decoding="async" decoding="async"
/> />
<MkA class="text" :to="notePage(note)"> <MkA class="text" :to="notePage(note)">
@ -34,13 +34,14 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, defineAsyncComponent, ref, toRef, watch } from "vue"; import { ref, watch } from "vue";
import * as misskey from "calckey-js";
import MarqueeText from "@/components/MkMarquee.vue"; import MarqueeText from "@/components/MkMarquee.vue";
import * as os from "@/os"; import * as os from "@/os";
import { useInterval } from "@/scripts/use-interval"; import { useInterval } from "@/scripts/use-interval";
import { getNoteSummary } from "@/scripts/get-note-summary"; import { getNoteSummary } from "@/scripts/get-note-summary";
import { notePage } from "@/filters/note"; import { notePage } from "@/filters/note";
import { resolveNote } from "@/scripts-mag/mag-util";
import { packed } from "magnetar-common";
const props = defineProps<{ const props = defineProps<{
userListId?: string; userListId?: string;
@ -51,7 +52,7 @@ const props = defineProps<{
refreshIntervalSec?: number; refreshIntervalSec?: number;
}>(); }>();
const notes = ref<misskey.entities.Note[]>([]); const notes = ref<packed.PackNoteMaybeFull[]>([]);
const fetching = ref(true); const fetching = ref(true);
let key = $ref(0); let key = $ref(0);
@ -59,8 +60,8 @@ const tick = () => {
if (props.userListId == null) return; if (props.userListId == null) return;
os.api("notes/user-list-timeline", { os.api("notes/user-list-timeline", {
listId: props.userListId, listId: props.userListId,
}).then((res) => { }).then(async (res) => {
notes.value = res; notes.value = await Promise.all(res.map(resolveNote));
fetching.value = false; fetching.value = false;
key++; key++;
}); });

View File

@ -63,8 +63,8 @@
> >
<small <small
>Powered by >Powered by
<a href="https://calckey.org/" target="_blank" <a href="https://git.astolfo.cool/natty/magnetar" target="_blank"
>Calckey</a >Magnetar</a
></small ></small
> >
</div> </div>

View File

@ -18,8 +18,8 @@
> >
<small <small
>Powered by >Powered by
<a href="https://calckey.org/" target="_blank" <a href="https://git.astolfo.cool/natty/magnetar" target="_blank"
>Calckey</a >Magnetar</a
></small ></small
> >
</div> </div>

View File

@ -29,7 +29,7 @@
<div v-if="info" class="page active link"> <div v-if="info" class="page active link">
<div class="title"> <div class="title">
<i v-if="info.icon" class="icon" :class="info.icon"></i> <i v-if="info.icon" class="icon" :class="info.icon"></i>
<MkAvatar <MagAvatarResolvingProxy
v-else-if="info.avatar" v-else-if="info.avatar"
class="avatar" class="avatar"
:user="info.avatar" :user="info.avatar"
@ -74,7 +74,7 @@
</button> </button>
<div v-if="info" class="title"> <div v-if="info" class="title">
<i v-if="info.icon" class="icon" :class="info.icon"></i> <i v-if="info.icon" class="icon" :class="info.icon"></i>
<MkAvatar <MagAvatarResolvingProxy
v-else-if="info.avatar" v-else-if="info.avatar"
class="avatar" class="avatar"
:user="info.avatar" :user="info.avatar"

View File

@ -69,8 +69,8 @@
> >
<small <small
>Powered by >Powered by
<a href="https://calckey.org/" target="_blank" <a href="https://git.astolfo.cool/natty/magnetar" target="_blank"
>Calckey</a >Magnetar</a
></small ></small
> >
</div> </div>