fix type errors of components
This commit is contained in:
parent
f422842aef
commit
393ab2590d
20 changed files with 170 additions and 112 deletions
|
@ -16,7 +16,7 @@
|
|||
v-else
|
||||
class="bghgjjyj _button"
|
||||
:class="{ inline, primary, gradate, danger, rounded, full, mini }"
|
||||
:to="to"
|
||||
:to="to!"
|
||||
@mousedown="onMousedown"
|
||||
>
|
||||
<div ref="ripples" class="ripples"></div>
|
||||
|
@ -36,6 +36,7 @@ const props = defineProps<{
|
|||
gradate?: boolean;
|
||||
rounded?: boolean;
|
||||
inline?: boolean;
|
||||
// FIXME: if `link`, `to` is necessary
|
||||
link?: boolean;
|
||||
to?: string;
|
||||
autofocus?: boolean;
|
||||
|
|
|
@ -28,11 +28,11 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import {} from "vue";
|
||||
import type { Ref } from "vue";
|
||||
import MkTooltip from "./MkTooltip.vue";
|
||||
|
||||
const props = defineProps<{
|
||||
showing: boolean;
|
||||
showing: Ref<boolean>;
|
||||
x: number;
|
||||
y: number;
|
||||
title?: string;
|
||||
|
|
|
@ -104,7 +104,7 @@
|
|||
</MkInput>
|
||||
<MkTextarea
|
||||
v-if="input && input.type === 'paragraph'"
|
||||
v-model="inputValue"
|
||||
v-model="(inputValue as string)"
|
||||
autofocus
|
||||
type="paragraph"
|
||||
:placeholder="input.placeholder || undefined"
|
||||
|
@ -204,7 +204,16 @@ import { i18n } from "@/i18n";
|
|||
import iconify from "@/scripts/icon";
|
||||
|
||||
interface Input {
|
||||
type: HTMLInputElement["type"];
|
||||
type?:
|
||||
| "text"
|
||||
| "number"
|
||||
| "password"
|
||||
| "email"
|
||||
| "url"
|
||||
| "date"
|
||||
| "time"
|
||||
| "search"
|
||||
| "paragraph";
|
||||
placeholder?: string | null;
|
||||
autocomplete?: string;
|
||||
default: string | number | null;
|
||||
|
@ -237,8 +246,8 @@ const props = withDefaults(
|
|||
| "question"
|
||||
| "waiting"
|
||||
| "search";
|
||||
title: string;
|
||||
text?: string;
|
||||
title?: string | null;
|
||||
text?: string | null;
|
||||
isPlaintext?: boolean;
|
||||
input?: Input;
|
||||
select?: Select;
|
||||
|
@ -246,7 +255,7 @@ const props = withDefaults(
|
|||
actions?: {
|
||||
text: string;
|
||||
primary?: boolean;
|
||||
callback: (...args: any[]) => void;
|
||||
callback: () => void;
|
||||
}[];
|
||||
showOkButton?: boolean;
|
||||
showCancelButton?: boolean;
|
||||
|
@ -268,7 +277,10 @@ const props = withDefaults(
|
|||
);
|
||||
|
||||
const emit = defineEmits<{
|
||||
(ev: "done", v: { canceled: boolean; result: any }): void;
|
||||
(
|
||||
ev: "done",
|
||||
v: { canceled: boolean; result?: string | number | boolean | null },
|
||||
): void;
|
||||
(ev: "closed"): void;
|
||||
}>();
|
||||
|
||||
|
@ -306,7 +318,7 @@ const okButtonDisabled = computed<boolean>(() => {
|
|||
|
||||
const inputEl = ref<typeof MkInput>();
|
||||
|
||||
function done(canceled: boolean, result?) {
|
||||
function done(canceled: boolean, result?: string | number | boolean | null) {
|
||||
emit("done", { canceled, result });
|
||||
modal.value?.close(null);
|
||||
}
|
||||
|
@ -342,12 +354,12 @@ function onInputKeydown(evt: KeyboardEvent) {
|
|||
}
|
||||
}
|
||||
|
||||
function formatDateToYYYYMMDD(date) {
|
||||
const year = date.getFullYear();
|
||||
const month = ("0" + (date.getMonth() + 1)).slice(-2);
|
||||
const day = ("0" + (date.getDate() + 1)).slice(-2);
|
||||
return `${year}-${month}-${day}`;
|
||||
}
|
||||
// function formatDateToYYYYMMDD(date) {
|
||||
// const year = date.getFullYear();
|
||||
// const month = ("0" + (date.getMonth() + 1)).slice(-2);
|
||||
// const day = ("0" + (date.getDate() + 1)).slice(-2);
|
||||
// return `${year}-${month}-${day}`;
|
||||
// }
|
||||
|
||||
/**
|
||||
* Appends a new search parameter to the value in the input field.
|
||||
|
@ -355,18 +367,18 @@ function formatDateToYYYYMMDD(date) {
|
|||
* begin typing a new criteria.
|
||||
* @param value The value to append.
|
||||
*/
|
||||
function appendFilter(value: string) {
|
||||
return (
|
||||
[
|
||||
typeof inputValue.value === "string"
|
||||
? inputValue.value.trim()
|
||||
: inputValue.value,
|
||||
value,
|
||||
]
|
||||
.join(" ")
|
||||
.trim() + " "
|
||||
);
|
||||
}
|
||||
// function appendFilter(value: string) {
|
||||
// return (
|
||||
// [
|
||||
// typeof inputValue.value === "string"
|
||||
// ? inputValue.value.trim()
|
||||
// : inputValue.value,
|
||||
// value,
|
||||
// ]
|
||||
// .join(" ")
|
||||
// .trim() + " "
|
||||
// );
|
||||
// }
|
||||
|
||||
onMounted(() => {
|
||||
document.addEventListener("keydown", onKeydown);
|
||||
|
|
|
@ -253,7 +253,7 @@ function onStreamDriveFolderDeleted(folderId: string) {
|
|||
removeFolder(folderId);
|
||||
}
|
||||
|
||||
function onDragover(ev: DragEvent): any {
|
||||
function onDragover(ev: DragEvent) {
|
||||
if (!ev.dataTransfer) return;
|
||||
|
||||
// ドラッグ元が自分自身の所有するアイテムだったら
|
||||
|
@ -285,7 +285,7 @@ function onDragleave() {
|
|||
draghover.value = false;
|
||||
}
|
||||
|
||||
function onDrop(ev: DragEvent): any {
|
||||
function onDrop(ev: DragEvent) {
|
||||
draghover.value = false;
|
||||
|
||||
if (!ev.dataTransfer) return;
|
||||
|
@ -493,14 +493,12 @@ function move(target?: entities.DriveFolder) {
|
|||
if (!target) {
|
||||
goRoot();
|
||||
return;
|
||||
} else if (typeof target === "object") {
|
||||
target = target.id;
|
||||
}
|
||||
|
||||
fetching.value = true;
|
||||
|
||||
os.api("drive/folders/show", {
|
||||
folderId: target,
|
||||
folderId: target.id,
|
||||
}).then((folderToMove) => {
|
||||
folder.value = folderToMove;
|
||||
hierarchyFolders.value = [];
|
||||
|
|
|
@ -12,12 +12,12 @@
|
|||
:user="notification.note.user"
|
||||
/>
|
||||
<MkAvatar
|
||||
v-else-if="notification.user"
|
||||
v-else-if="'user' in notification"
|
||||
class="icon"
|
||||
:user="notification.user"
|
||||
/>
|
||||
<img
|
||||
v-else-if="notification.icon"
|
||||
v-else-if="'icon' in notification && notification.icon"
|
||||
class="icon"
|
||||
:src="notification.icon"
|
||||
alt=""
|
||||
|
@ -95,7 +95,7 @@
|
|||
i18n.ts._notification.pollEnded
|
||||
}}</span>
|
||||
<MkA
|
||||
v-else-if="notification.user"
|
||||
v-else-if="'user' in notification"
|
||||
v-user-preview="notification.user.id"
|
||||
class="name"
|
||||
:to="userPage(notification.user)"
|
||||
|
@ -133,7 +133,7 @@
|
|||
:plain="true"
|
||||
:nowrap="!full"
|
||||
:lang="notification.note.lang"
|
||||
:custom-emojis="notification.note.renote.emojis"
|
||||
:custom-emojis="notification.note.renote!.emojis"
|
||||
/>
|
||||
</MkA>
|
||||
<MkA
|
||||
|
@ -212,6 +212,7 @@
|
|||
style="opacity: 0.7"
|
||||
>{{ i18n.ts.youGotNewFollower }}
|
||||
<div v-if="full && !hideFollowButton">
|
||||
<!-- FIXME: Provide a UserDetailed here -->
|
||||
<MkFollowButton
|
||||
:user="notification.user"
|
||||
:full="true"
|
||||
|
@ -269,7 +270,7 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { onMounted, onUnmounted, ref, watch } from "vue";
|
||||
import { onMounted, onUnmounted, ref, toRef, watch } from "vue";
|
||||
import type { entities } from "firefish-js";
|
||||
import XReactionIcon from "@/components/MkReactionIcon.vue";
|
||||
import MkFollowButton from "@/components/MkFollowButton.vue";
|
||||
|
@ -284,6 +285,8 @@ import { useTooltip } from "@/scripts/use-tooltip";
|
|||
import { defaultStore } from "@/store";
|
||||
import { instance } from "@/instance";
|
||||
import icon from "@/scripts/icon";
|
||||
import type { Connection } from "firefish-js/src/streaming";
|
||||
import type { Channels } from "firefish-js/src/streaming.types";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
|
@ -299,8 +302,8 @@ const props = withDefaults(
|
|||
|
||||
const stream = useStream();
|
||||
|
||||
const elRef = ref<HTMLElement>(null);
|
||||
const reactionRef = ref(null);
|
||||
const elRef = ref<HTMLElement | null>(null);
|
||||
const reactionRef = ref<InstanceType<typeof XReactionIcon> | null>(null);
|
||||
|
||||
const hideFollowButton = defaultStore.state.hideFollowButtons;
|
||||
const showEmojiReactions =
|
||||
|
@ -311,7 +314,7 @@ const defaultReaction = ["⭐", "👍", "❤️"].includes(instance.defaultReact
|
|||
: "⭐";
|
||||
|
||||
let readObserver: IntersectionObserver | undefined;
|
||||
let connection;
|
||||
let connection: Connection<Channels["main"]> | null = null;
|
||||
|
||||
onMounted(() => {
|
||||
if (!props.notification.isRead) {
|
||||
|
@ -323,13 +326,13 @@ onMounted(() => {
|
|||
observer.disconnect();
|
||||
});
|
||||
|
||||
readObserver.observe(elRef.value);
|
||||
readObserver.observe(elRef.value!);
|
||||
|
||||
connection = stream.useChannel("main");
|
||||
connection.on("readAllNotifications", () => readObserver.disconnect());
|
||||
connection.on("readAllNotifications", () => readObserver!.disconnect());
|
||||
|
||||
watch(props.notification.isRead, () => {
|
||||
readObserver.disconnect();
|
||||
watch(toRef(props.notification.isRead), () => {
|
||||
readObserver!.disconnect();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
@ -344,38 +347,47 @@ const groupInviteDone = ref(false);
|
|||
|
||||
const acceptFollowRequest = () => {
|
||||
followRequestDone.value = true;
|
||||
os.api("following/requests/accept", { userId: props.notification.user.id });
|
||||
os.api("following/requests/accept", {
|
||||
userId: (props.notification as entities.ReceiveFollowRequestNotification)
|
||||
.user.id,
|
||||
});
|
||||
};
|
||||
|
||||
const rejectFollowRequest = () => {
|
||||
followRequestDone.value = true;
|
||||
os.api("following/requests/reject", { userId: props.notification.user.id });
|
||||
os.api("following/requests/reject", {
|
||||
userId: (props.notification as entities.ReceiveFollowRequestNotification)
|
||||
.user.id,
|
||||
});
|
||||
};
|
||||
|
||||
const acceptGroupInvitation = () => {
|
||||
groupInviteDone.value = true;
|
||||
os.apiWithDialog("users/groups/invitations/accept", {
|
||||
invitationId: props.notification.invitation.id,
|
||||
invitationId: (props.notification as entities.GroupInvitedNotification)
|
||||
.invitation.id,
|
||||
});
|
||||
};
|
||||
|
||||
const rejectGroupInvitation = () => {
|
||||
groupInviteDone.value = true;
|
||||
os.api("users/groups/invitations/reject", {
|
||||
invitationId: props.notification.invitation.id,
|
||||
invitationId: (props.notification as entities.GroupInvitedNotification)
|
||||
.invitation.id,
|
||||
});
|
||||
};
|
||||
|
||||
useTooltip(reactionRef, (showing) => {
|
||||
const n = props.notification as entities.ReactionNotification;
|
||||
os.popup(
|
||||
XReactionTooltip,
|
||||
{
|
||||
showing,
|
||||
reaction: props.notification.reaction
|
||||
? props.notification.reaction.replace(/^:(\w+):$/, ":$1@.:")
|
||||
: props.notification.reaction,
|
||||
emojis: props.notification.note.emojis,
|
||||
targetElement: reactionRef.value.$el,
|
||||
reaction: n.reaction
|
||||
? n.reaction.replace(/^:(\w+):$/, ":$1@.:")
|
||||
: n.reaction,
|
||||
emojis: n.note.emojis,
|
||||
targetElement: reactionRef.value!.$el,
|
||||
},
|
||||
{},
|
||||
"closed",
|
||||
|
|
|
@ -3,7 +3,7 @@
|
|||
:to="`/@${page.user.username}/pages/${page.name}`"
|
||||
class="vhpxefrj _block"
|
||||
tabindex="-1"
|
||||
:behavior="`${ui === 'deck' ? 'window' : null}`"
|
||||
:behavior="ui === 'deck' ? 'window' : null"
|
||||
>
|
||||
<div
|
||||
v-if="page.eyeCatchingImage"
|
||||
|
@ -36,9 +36,10 @@
|
|||
<script lang="ts" setup>
|
||||
import { userName } from "@/filters/user";
|
||||
import { ui } from "@/config";
|
||||
import type { entities } from "firefish-js";
|
||||
|
||||
defineProps<{
|
||||
page: any;
|
||||
page: entities.Page;
|
||||
}>();
|
||||
</script>
|
||||
|
||||
|
|
|
@ -56,23 +56,22 @@ const router = new Router(routes, props.initialPath);
|
|||
|
||||
const pageMetadata = ref<null | ComputedRef<PageMetadata>>();
|
||||
const windowEl = ref<InstanceType<typeof XWindow>>();
|
||||
const history = ref<{ path: string; key: any }[]>([
|
||||
const history = ref<{ path: string; key: string }[]>([
|
||||
{
|
||||
path: router.getCurrentPath(),
|
||||
key: router.getCurrentKey(),
|
||||
},
|
||||
]);
|
||||
const buttonsLeft = computed(() => {
|
||||
const buttons = [];
|
||||
|
||||
if (history.value.length > 1) {
|
||||
buttons.push({
|
||||
icon: `${icon("ph-caret-left")}`,
|
||||
onClick: back,
|
||||
});
|
||||
return [
|
||||
{
|
||||
icon: `${icon("ph-caret-left")}`,
|
||||
onClick: back,
|
||||
},
|
||||
];
|
||||
}
|
||||
|
||||
return buttons;
|
||||
return [];
|
||||
});
|
||||
const buttonsRight = computed(() => {
|
||||
const buttons = [
|
||||
|
@ -114,7 +113,7 @@ const contextmenu = computed(() => [
|
|||
text: i18n.ts.openInNewTab,
|
||||
action: () => {
|
||||
window.open(url + router.getCurrentPath(), "_blank");
|
||||
windowEl.value.close();
|
||||
windowEl.value!.close();
|
||||
},
|
||||
},
|
||||
{
|
||||
|
@ -135,17 +134,17 @@ function back() {
|
|||
}
|
||||
|
||||
function close() {
|
||||
windowEl.value.close();
|
||||
windowEl.value!.close();
|
||||
}
|
||||
|
||||
function expand() {
|
||||
mainRouter.push(router.getCurrentPath(), "forcePage");
|
||||
windowEl.value.close();
|
||||
windowEl.value!.close();
|
||||
}
|
||||
|
||||
function popout() {
|
||||
_popout(router.getCurrentPath(), windowEl.value.$el);
|
||||
windowEl.value.close();
|
||||
_popout(router.getCurrentPath(), windowEl.value!.$el);
|
||||
windowEl.value!.close();
|
||||
}
|
||||
|
||||
defineExpose({
|
||||
|
|
|
@ -94,15 +94,14 @@ const props = defineProps<{
|
|||
};
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
(
|
||||
ev: "update:modelValue",
|
||||
"update:modelValue": [
|
||||
v: {
|
||||
expiresAt: string;
|
||||
expiredAfter: number;
|
||||
expiresAt?: number;
|
||||
expiredAfter?: number | null;
|
||||
choices: string[];
|
||||
multiple: boolean;
|
||||
},
|
||||
): void;
|
||||
];
|
||||
}>();
|
||||
|
||||
const choices = ref(props.modelValue.choices);
|
||||
|
@ -147,19 +146,19 @@ function get() {
|
|||
};
|
||||
|
||||
const calcAfter = () => {
|
||||
let base = Number.parseInt(after.value);
|
||||
let base = Number.parseInt(after.value.toString());
|
||||
switch (unit.value) {
|
||||
// biome-ignore lint/suspicious/noFallthroughSwitchClause: Fallthrough intentially
|
||||
case "day":
|
||||
base *= 24;
|
||||
// fallthrough
|
||||
// biome-ignore lint/suspicious/noFallthroughSwitchClause: Fallthrough intentially
|
||||
case "hour":
|
||||
base *= 60;
|
||||
// fallthrough
|
||||
// biome-ignore lint/suspicious/noFallthroughSwitchClause: Fallthrough intentially
|
||||
case "minute":
|
||||
base *= 60;
|
||||
// fallthrough
|
||||
case "second":
|
||||
return (base *= 1000);
|
||||
return base * 1000;
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
|
|
@ -1136,11 +1136,11 @@ async function post() {
|
|||
nextTick(() => autosize.update(textareaEl.value));
|
||||
});
|
||||
})
|
||||
.catch((err) => {
|
||||
.catch((err: { message: string; id: string }) => {
|
||||
posting.value = false;
|
||||
os.alert({
|
||||
type: "error",
|
||||
text: err.message + "\n" + (err as any).id,
|
||||
text: `${err.message}\n${err.id}`,
|
||||
});
|
||||
});
|
||||
vibrate([10, 20, 10, 20, 10, 20, 60]);
|
||||
|
|
|
@ -9,9 +9,11 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { entities } from "firefish-js";
|
||||
|
||||
defineProps<{
|
||||
reaction: string;
|
||||
customEmojis?: any[]; // TODO
|
||||
customEmojis?: entities.EmojiLite[];
|
||||
noStyle?: boolean;
|
||||
}>();
|
||||
</script>
|
||||
|
|
|
@ -3,6 +3,7 @@
|
|||
ref="tooltip"
|
||||
:target-element="targetElement"
|
||||
:max-width="340"
|
||||
:showing="showing"
|
||||
@closed="emit('closed')"
|
||||
>
|
||||
<div class="beeadbfb">
|
||||
|
@ -18,12 +19,15 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Ref } from "vue";
|
||||
import MkTooltip from "./MkTooltip.vue";
|
||||
import XReactionIcon from "@/components/MkReactionIcon.vue";
|
||||
import type { entities } from "firefish-js";
|
||||
|
||||
defineProps<{
|
||||
showing: Ref<boolean>;
|
||||
reaction: string;
|
||||
emojis: any[]; // TODO
|
||||
emojis: entities.EmojiLite[];
|
||||
targetElement: HTMLElement;
|
||||
}>();
|
||||
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
:target-element="targetElement"
|
||||
:max-width="340"
|
||||
@closed="emit('closed')"
|
||||
:showing="showing"
|
||||
>
|
||||
<div class="bqxuuuey">
|
||||
<div class="reaction">
|
||||
|
@ -29,15 +30,18 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Ref } from "vue";
|
||||
import MkTooltip from "./MkTooltip.vue";
|
||||
import XReactionIcon from "@/components/MkReactionIcon.vue";
|
||||
import type { entities } from "firefish-js";
|
||||
|
||||
defineProps<{
|
||||
showing: Ref<boolean>;
|
||||
reaction: string;
|
||||
users: any[]; // TODO
|
||||
users: entities.User[]; // TODO
|
||||
count: number;
|
||||
emojis: any[]; // TODO
|
||||
targetElement: HTMLElement;
|
||||
emojis: entities.EmojiLite[]; // TODO
|
||||
targetElement?: HTMLElement;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
|
|
@ -89,7 +89,7 @@ useTooltip(
|
|||
emojis: props.note.emojis,
|
||||
users,
|
||||
count: props.count,
|
||||
targetElement: buttonRef.value,
|
||||
targetElement: buttonRef.value!,
|
||||
},
|
||||
{},
|
||||
"closed",
|
||||
|
|
|
@ -46,7 +46,7 @@ const buttonRef = ref<HTMLElement>();
|
|||
const canRenote = computed(
|
||||
() =>
|
||||
["public", "home"].includes(props.note.visibility) ||
|
||||
props.note.userId === me.id,
|
||||
props.note.userId === me?.id,
|
||||
);
|
||||
|
||||
useTooltip(buttonRef, async (showing) => {
|
||||
|
|
|
@ -5,13 +5,13 @@
|
|||
@after-leave="emit('closed')"
|
||||
>
|
||||
<div
|
||||
v-show="showing"
|
||||
v-show="unref(showing)"
|
||||
ref="el"
|
||||
class="buebdbiu _acrylic _shadow"
|
||||
:style="{ zIndex, maxWidth: maxWidth + 'px' }"
|
||||
>
|
||||
<slot>
|
||||
<Mfm v-if="asMfm" :text="text" />
|
||||
<Mfm v-if="asMfm" :text="text!" />
|
||||
<span v-else>{{ text }}</span>
|
||||
</slot>
|
||||
</div>
|
||||
|
@ -19,15 +19,22 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import { nextTick, onMounted, onUnmounted, ref } from "vue";
|
||||
import {
|
||||
type MaybeRef,
|
||||
nextTick,
|
||||
onMounted,
|
||||
onUnmounted,
|
||||
ref,
|
||||
unref,
|
||||
} from "vue";
|
||||
import * as os from "@/os";
|
||||
import { calcPopupPosition } from "@/scripts/popup-position";
|
||||
import { defaultStore } from "@/store";
|
||||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
showing: boolean;
|
||||
targetElement?: HTMLElement;
|
||||
showing: MaybeRef<boolean>;
|
||||
targetElement?: HTMLElement | null;
|
||||
x?: number;
|
||||
y?: number;
|
||||
text?: string;
|
||||
|
@ -40,6 +47,7 @@ const props = withDefaults(
|
|||
maxWidth: 250,
|
||||
direction: "top",
|
||||
innerMargin: 0,
|
||||
targetElement: null,
|
||||
},
|
||||
);
|
||||
|
||||
|
@ -51,7 +59,7 @@ const el = ref<HTMLElement>();
|
|||
const zIndex = os.claimZIndex("high");
|
||||
|
||||
function setPosition() {
|
||||
const data = calcPopupPosition(el.value, {
|
||||
const data = calcPopupPosition(el.value!, {
|
||||
anchorElement: props.targetElement,
|
||||
direction: props.direction,
|
||||
align: "center",
|
||||
|
@ -60,12 +68,12 @@ function setPosition() {
|
|||
y: props.y,
|
||||
});
|
||||
|
||||
el.value.style.transformOrigin = data.transformOrigin;
|
||||
el.value.style.left = data.left + "px";
|
||||
el.value.style.top = data.top + "px";
|
||||
el.value!.style.transformOrigin = data.transformOrigin;
|
||||
el.value!.style.left = `${data.left}px`;
|
||||
el.value!.style.top = `${data.top}px`;
|
||||
}
|
||||
|
||||
let loopHandler;
|
||||
let loopHandler: number;
|
||||
|
||||
onMounted(() => {
|
||||
nextTick(() => {
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
:target-element="targetElement"
|
||||
:max-width="250"
|
||||
@closed="emit('closed')"
|
||||
:showing="showing"
|
||||
>
|
||||
<div class="beaffaef">
|
||||
<div v-for="u in users" :key="u.id" class="user">
|
||||
|
@ -18,12 +19,15 @@
|
|||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
import type { Ref } from "vue";
|
||||
import MkTooltip from "./MkTooltip.vue";
|
||||
import type { entities } from "firefish-js";
|
||||
|
||||
defineProps<{
|
||||
users: any[]; // TODO
|
||||
showing: Ref<boolean>;
|
||||
users: entities.User[];
|
||||
count: number;
|
||||
targetElement: HTMLElement;
|
||||
targetElement?: HTMLElement;
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<{
|
||||
|
|
|
@ -85,7 +85,7 @@ import icon from "@/scripts/icon";
|
|||
interface Widget {
|
||||
name: string;
|
||||
id: string;
|
||||
data: Record<string, any>;
|
||||
data: Record<string, unknown>;
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
|
@ -137,12 +137,12 @@ function onContextmenu(widget: Widget, ev: MouseEvent) {
|
|||
return isLink(el.parentElement);
|
||||
}
|
||||
};
|
||||
if (isLink(ev.target)) return;
|
||||
if (isLink(ev.target as HTMLElement)) return;
|
||||
if (
|
||||
["INPUT", "TEXTAREA", "IMG", "VIDEO", "CANVAS"].includes(
|
||||
ev.target.tagName,
|
||||
(ev.target as HTMLElement).tagName,
|
||||
) ||
|
||||
ev.target.attributes.contenteditable
|
||||
(ev.target as HTMLElement).getAttribute("contentEditable")
|
||||
)
|
||||
return;
|
||||
if (window.getSelection()?.toString() !== "") return;
|
||||
|
|
|
@ -22,7 +22,7 @@ import icon from "@/scripts/icon";
|
|||
|
||||
const props = withDefaults(
|
||||
defineProps<{
|
||||
to?: string;
|
||||
to: string;
|
||||
activeClass?: null | string;
|
||||
behavior?: null | "window" | "browser" | "modalWindow";
|
||||
}>(),
|
||||
|
|
|
@ -210,11 +210,13 @@ interface VueComponentConstructor<P, E> {
|
|||
emits?: E;
|
||||
}
|
||||
|
||||
type NonArrayAble<A> = A extends Array<unknown> ? never : A;
|
||||
|
||||
export async function popup<Props, Emits>(
|
||||
component: VueComponentConstructor<Props, Emits>,
|
||||
props: Props & Record<string, unknown>,
|
||||
events: Partial<Emits> = {},
|
||||
disposeEvent?: string,
|
||||
props: Props,
|
||||
events: Partial<NonArrayAble<NonNullable<Emits>>> = {},
|
||||
disposeEvent?: keyof Partial<NonArrayAble<NonNullable<Emits>>>,
|
||||
) {
|
||||
markRaw(component);
|
||||
|
||||
|
@ -227,7 +229,7 @@ export async function popup<Props, Emits>(
|
|||
};
|
||||
const state = {
|
||||
component,
|
||||
props,
|
||||
props: props as Record<string, unknown>,
|
||||
events: disposeEvent
|
||||
? {
|
||||
...events,
|
||||
|
|
|
@ -20,6 +20,16 @@ export type UserLite = {
|
|||
movedToUri: any;
|
||||
emojis: EmojiLite[];
|
||||
instance?: InstanceLite;
|
||||
avatarColor: null;
|
||||
emojiModPerm: "unauthorized" | "add" | "mod" | "full";
|
||||
isAdmin?: boolean;
|
||||
isModerator?: boolean;
|
||||
isBot?: boolean;
|
||||
isLocked: boolean;
|
||||
isIndexable: boolean;
|
||||
isCat?: boolean;
|
||||
speakAsCat?: boolean;
|
||||
driveCapacityOverrideMb: number | null,
|
||||
};
|
||||
|
||||
export type UserDetailed = UserLite & {
|
||||
|
@ -46,7 +56,6 @@ export type UserDetailed = UserLite & {
|
|||
isCat: boolean;
|
||||
isFollowed: boolean;
|
||||
isFollowing: boolean;
|
||||
isLocked: boolean;
|
||||
isModerator: boolean;
|
||||
isMuted: boolean;
|
||||
isRenoteMuted: boolean;
|
||||
|
@ -228,7 +237,10 @@ export interface RenoteNotification extends BaseNotification {
|
|||
type: "renote";
|
||||
user: User;
|
||||
userId: User["id"];
|
||||
note: Note;
|
||||
note: Note & {
|
||||
renote: Note,
|
||||
renoteId: string,
|
||||
};
|
||||
}
|
||||
export interface QuoteNotification extends BaseNotification {
|
||||
type: "quote";
|
||||
|
|
Loading…
Reference in a new issue