fix types of component

This commit is contained in:
Lhcfl 2024-04-12 11:16:26 +08:00
parent f3b189a70c
commit 5da03666b2
12 changed files with 68 additions and 45 deletions

View file

@ -21,7 +21,8 @@
"useImportType": "warn", "useImportType": "warn",
"useShorthandFunctionType": "warn", "useShorthandFunctionType": "warn",
"useTemplate": "warn", "useTemplate": "warn",
"noNonNullAssertion": "off" "noNonNullAssertion": "off",
"useNodejsImportProtocol": "off"
} }
} }
} }

View file

@ -181,12 +181,15 @@ function describe() {
image: props.file, image: props.file,
}, },
{ {
done: (result) => { done: (result: {
canceled: boolean,
result?: string | null,
}) => {
if (!result || result.canceled) return; if (!result || result.canceled) return;
const comment = result.result; const comment = result.result;
os.api("drive/files/update", { os.api("drive/files/update", {
fileId: props.file.id, fileId: props.file.id,
comment: comment.length === 0 ? null : comment, comment: comment || null,
}); });
}, },
}, },

View file

@ -73,7 +73,10 @@ import { deviceKind } from "@/scripts/device-kind";
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
src?: HTMLElement; src?: HTMLElement;
anchor?: { x: string; y: string }; anchor?: {
x: "left" | "center" | "right";
y: "top" | "center" | "bottom";
};
}>(), }>(),
{ {
anchor: () => ({ x: "right", y: "center" }), anchor: () => ({ x: "right", y: "center" }),

View file

@ -100,7 +100,7 @@ const props = withDefaults(
); );
const emit = defineEmits<{ const emit = defineEmits<{
done: [v: { canceled: boolean; result?: string | null }]; done: [result: { canceled: boolean; result?: string | null }];
closed: []; closed: [];
}>(); }>();

View file

@ -22,7 +22,7 @@
media.type.startsWith('video') || media.type.startsWith('video') ||
media.type.startsWith('image') media.type.startsWith('image')
" "
:key="media.id" :key="`m-${media.id}`"
:class="{ image: media.type.startsWith('image') }" :class="{ image: media.type.startsWith('image') }"
:data-id="media.id" :data-id="media.id"
:media="media" :media="media"
@ -30,7 +30,7 @@
/> />
<XModPlayer <XModPlayer
v-else-if="isModule(media)" v-else-if="isModule(media)"
:key="media.id" :key="`p-${media.id}`"
:module="media" :module="media"
/> />
</template> </template>
@ -48,7 +48,7 @@ import "photoswipe/style.css";
import XBanner from "@/components/MkMediaBanner.vue"; import XBanner from "@/components/MkMediaBanner.vue";
import XMedia from "@/components/MkMedia.vue"; import XMedia from "@/components/MkMedia.vue";
import XModPlayer from "@/components/MkModPlayer.vue"; import XModPlayer from "@/components/MkModPlayer.vue";
import * as os from "@/os"; // import * as os from "@/os";
import { import {
FILE_EXT_TRACKER_MODULES, FILE_EXT_TRACKER_MODULES,
FILE_TYPE_BROWSERSAFE, FILE_TYPE_BROWSERSAFE,
@ -61,8 +61,8 @@ const props = defineProps<{
inDm?: boolean; inDm?: boolean;
}>(); }>();
const gallery = ref(null); const gallery = ref<HTMLElement | null>(null);
const pswpZIndex = os.claimZIndex("middle"); // const pswpZIndex = os.claimZIndex("middle");
onMounted(() => { onMounted(() => {
const lightbox = new PhotoSwipeLightbox({ const lightbox = new PhotoSwipeLightbox({
@ -79,7 +79,7 @@ onMounted(() => {
src: media.url, src: media.url,
w: media.properties.width, w: media.properties.width,
h: media.properties.height, h: media.properties.height,
alt: media.comment, alt: media.comment || undefined,
}; };
if ( if (
media.properties.orientation != null && media.properties.orientation != null &&
@ -89,7 +89,7 @@ onMounted(() => {
} }
return item; return item;
}), }),
gallery: gallery.value, gallery: gallery.value || undefined,
children: ".image", children: ".image",
thumbSelector: ".image img", thumbSelector: ".image img",
loop: false, loop: false,
@ -119,9 +119,13 @@ onMounted(() => {
// element is children // element is children
const { element } = itemData; const { element } = itemData;
if (element == null) return;
const id = element.dataset.id; const id = element.dataset.id;
const file = props.mediaList.find((media) => media.id === id); const file = props.mediaList.find((media) => media.id === id);
if (file == null) return;
itemData.src = file.url; itemData.src = file.url;
itemData.w = Number(file.properties.width); itemData.w = Number(file.properties.width);
itemData.h = Number(file.properties.height); itemData.h = Number(file.properties.height);
@ -132,12 +136,12 @@ onMounted(() => {
[itemData.w, itemData.h] = [itemData.h, itemData.w]; [itemData.w, itemData.h] = [itemData.h, itemData.w];
} }
itemData.msrc = file.thumbnailUrl; itemData.msrc = file.thumbnailUrl;
itemData.alt = file.comment; itemData.alt = file.comment || undefined;
itemData.thumbCropped = true; itemData.thumbCropped = true;
}); });
lightbox.on("uiRegister", () => { lightbox.on("uiRegister", () => {
lightbox.pswp.ui.registerElement({ lightbox.pswp?.ui?.registerElement({
name: "altText", name: "altText",
className: "pwsp__alt-text-container", className: "pwsp__alt-text-container",
appendTo: "wrapper", appendTo: "wrapper",
@ -146,7 +150,7 @@ onMounted(() => {
textBox.className = "pwsp__alt-text"; textBox.className = "pwsp__alt-text";
el.appendChild(textBox); el.appendChild(textBox);
const preventProp = function (ev: Event): void { const preventProp = (ev: Event): void => {
ev.stopPropagation(); ev.stopPropagation();
}; };
@ -158,7 +162,7 @@ onMounted(() => {
el.onpointermove = preventProp; el.onpointermove = preventProp;
pwsp.on("change", () => { pwsp.on("change", () => {
textBox.textContent = pwsp.currSlide.data.alt?.trim(); textBox.textContent = pwsp.currSlide?.data.alt?.trim() ?? null;
}); });
}, },
}); });
@ -168,7 +172,7 @@ onMounted(() => {
history.pushState(null, "", location.href); history.pushState(null, "", location.href);
addEventListener("popstate", close); addEventListener("popstate", close);
// This is a workaround. Not sure why, but when clicking to open, it doesn't move focus to the photoswipe. Preventing using esc to close. However when using keyboard to open it already focuses the lightbox fine. // This is a workaround. Not sure why, but when clicking to open, it doesn't move focus to the photoswipe. Preventing using esc to close. However when using keyboard to open it already focuses the lightbox fine.
lightbox.pswp.element.focus(); lightbox.pswp?.element?.focus();
}); });
lightbox.on("close", () => { lightbox.on("close", () => {
removeEventListener("popstate", close); removeEventListener("popstate", close);
@ -180,7 +184,7 @@ onMounted(() => {
function close() { function close() {
removeEventListener("popstate", close); removeEventListener("popstate", close);
history.forward(); history.forward();
lightbox.pswp.close(); lightbox.pswp?.close();
} }
}); });
@ -198,7 +202,7 @@ const isModule = (file: entities.DriveFile): boolean => {
return ( return (
FILE_TYPE_TRACKER_MODULES.includes(file.type) || FILE_TYPE_TRACKER_MODULES.includes(file.type) ||
FILE_EXT_TRACKER_MODULES.some((ext) => { FILE_EXT_TRACKER_MODULES.some((ext) => {
return file.name.toLowerCase().endsWith("." + ext); return file.name.toLowerCase().endsWith(`.${ext}`);
}) })
); );
}; };

View file

@ -23,7 +23,6 @@
:href="url" :href="url"
target="_blank" target="_blank"
rel="noopener" rel="noopener"
:style="{ background: bgCss }"
@click.stop @click.stop
> >
<span class="main"> <span class="main">
@ -54,7 +53,7 @@ const url = `/${canonical}`;
const isMe = const isMe =
isSignedIn && isSignedIn &&
`@${props.username}@${toUnicode(props.host)}`.toLowerCase() === `@${props.username}@${toUnicode(props.host)}`.toLowerCase() ===
`@${me.username}@${toUnicode(localHost)}`.toLowerCase(); `@${me!.username}@${toUnicode(localHost)}`.toLowerCase();
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View file

@ -37,8 +37,8 @@ function setPosition() {
const rect = props.targetElement.getBoundingClientRect(); const rect = props.targetElement.getBoundingClientRect();
const left = props.targetElement.offsetWidth; const left = props.targetElement.offsetWidth;
const top = rect.top - rootRect.top - 8; const top = rect.top - rootRect.top - 8;
el.value.style.left = left + "px"; el.value!.style.left = `${left}px`;
el.value.style.top = top + "px"; el.value!.style.top = `${top}px`;
} }
function onChildClosed(actioned?: boolean) { function onChildClosed(actioned?: boolean) {
@ -58,7 +58,7 @@ onMounted(() => {
defineExpose({ defineExpose({
checkHit: (ev: MouseEvent) => { checkHit: (ev: MouseEvent) => {
return ev.target === el.value || el.value.contains(ev.target); return ev.target === el.value || el.value?.contains(ev.target as Node);
}, },
}); });
</script> </script>

View file

@ -89,7 +89,8 @@
></span> ></span>
</a> </a>
<button <button
v-else-if="item.type === 'user' && !items.hidden" v-else-if="item.type === 'user'"
v-show="!item.hidden"
class="_button item" class="_button item"
:class="{ active: item.active }" :class="{ active: item.active }"
:disabled="item.active" :disabled="item.active"
@ -206,6 +207,7 @@ import {
onMounted, onMounted,
ref, ref,
watch, watch,
shallowRef,
} from "vue"; } from "vue";
import { FocusTrap } from "focus-trap-vue"; import { FocusTrap } from "focus-trap-vue";
import FormSwitch from "@/components/form/switch.vue"; import FormSwitch from "@/components/form/switch.vue";
@ -213,6 +215,7 @@ import type {
InnerMenuItem, InnerMenuItem,
MenuAction, MenuAction,
MenuItem, MenuItem,
MenuParent,
MenuPending, MenuPending,
} from "@/types/menu"; } from "@/types/menu";
import * as os from "@/os"; import * as os from "@/os";
@ -234,20 +237,24 @@ const props = defineProps<{
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{
(ev: "close", actioned?: boolean): void; close: [actioned?: boolean];
}>(); }>();
const itemsEl = ref<HTMLDivElement>(); const itemsEl = ref<HTMLDivElement>();
const items2: InnerMenuItem[] = ref([]); const items2 = shallowRef<InnerMenuItem[]>([]);
const child = ref<InstanceType<typeof XChild>>(); const child = ref<InstanceType<typeof XChild>>();
const childShowingItem = ref<MenuItem | null>(); const childShowingItem = ref<MenuItem | null>();
// FIXME: this is not used
const isActive = ref();
watch( watch(
() => props.items, () => props.items,
() => { () => {
// FIXME: what's this?
const items: (MenuItem | MenuPending)[] = [...props.items].filter( const items: (MenuItem | MenuPending)[] = [...props.items].filter(
(item) => item !== undefined, (item) => item !== undefined,
); );
@ -288,29 +295,29 @@ function onGlobalMousedown(event: MouseEvent) {
if ( if (
childTarget.value && childTarget.value &&
(event.target === childTarget.value || (event.target === childTarget.value ||
childTarget.value.contains(event.target)) childTarget.value.contains(event.target as Node))
) )
return; return;
if (child.value && child.value.checkHit(event)) return; if (child.value?.checkHit(event)) return;
closeChild(); closeChild();
} }
let childCloseTimer: null | number = null; let childCloseTimer: null | number = null;
function onItemMouseEnter(item) { function onItemMouseEnter(_item) {
childCloseTimer = window.setTimeout(() => { childCloseTimer = window.setTimeout(() => {
closeChild(); closeChild();
}, 300); }, 300);
} }
function onItemMouseLeave(item) { function onItemMouseLeave(_item) {
if (childCloseTimer) window.clearTimeout(childCloseTimer); if (childCloseTimer) window.clearTimeout(childCloseTimer);
} }
async function showChildren(item: MenuItem, ev: MouseEvent) { async function showChildren(item: MenuParent, ev: MouseEvent) {
if (props.asDrawer) { if (props.asDrawer) {
os.popupMenu(item.children, ev.currentTarget ?? ev.target); os.popupMenu(item.children, (ev.currentTarget ?? ev.target) as HTMLElement);
close(); close();
} else { } else {
childTarget.value = ev.currentTarget ?? ev.target; childTarget.value = (ev.currentTarget ?? ev.target) as HTMLElement;
childMenu.value = item.children; childMenu.value = item.children;
childShowingItem.value = item; childShowingItem.value = item;
} }

View file

@ -20,7 +20,7 @@
:stroke="color" :stroke="color"
stroke-width="2" stroke-width="2"
/> />
<circle :cx="headX" :cy="headY" r="3" :fill="color" /> <circle :cx="headX ?? undefined" :cy="headY ?? undefined" r="3" :fill="color" />
</svg> </svg>
</template> </template>

View file

@ -108,8 +108,11 @@ type ModalTypes = "popup" | "dialog" | "dialog:top" | "drawer";
const props = withDefaults( const props = withDefaults(
defineProps<{ defineProps<{
manualShowing?: boolean | null; manualShowing?: boolean | null;
anchor?: { x: string; y: string }; anchor?: {
src?: HTMLElement; x: "left" | "center" | "right";
y: "top" | "center" | "bottom";
};
src?: HTMLElement | null;
preferType?: ModalTypes | "auto"; preferType?: ModalTypes | "auto";
zPriority?: "low" | "middle" | "high"; zPriority?: "low" | "middle" | "high";
noOverlap?: boolean; noOverlap?: boolean;
@ -118,7 +121,7 @@ const props = withDefaults(
}>(), }>(),
{ {
manualShowing: null, manualShowing: null,
src: undefined, src: null,
anchor: () => ({ x: "center", y: "bottom" }), anchor: () => ({ x: "center", y: "bottom" }),
preferType: "auto", preferType: "auto",
zPriority: "low", zPriority: "low",
@ -139,6 +142,9 @@ const emit = defineEmits<{
provide("modal", true); provide("modal", true);
// FIXME: this may not used
const isActive = ref();
const maxHeight = ref<number>(); const maxHeight = ref<number>();
const fixed = ref(false); const fixed = ref(false);
const transformOrigin = ref("center"); const transformOrigin = ref("center");
@ -189,7 +195,7 @@ const transitionDuration = computed(() =>
let contentClicking = false; let contentClicking = false;
const focusedElement = document.activeElement; const focusedElement = document.activeElement as HTMLElement;
function close(_ev?, opts: { useSendAnimation?: boolean } = {}) { function close(_ev?, opts: { useSendAnimation?: boolean } = {}) {
// removeEventListener("popstate", close); // removeEventListener("popstate", close);
// if (props.preferType == "dialog") { // if (props.preferType == "dialog") {
@ -204,7 +210,7 @@ function close(_ev?, opts: { useSendAnimation?: boolean } = {}) {
showing.value = false; showing.value = false;
emit("close"); emit("close");
if (!props.noReturnFocus) { if (!props.noReturnFocus) {
focusedElement.focus(); focusedElement?.focus();
} }
} }
@ -235,8 +241,8 @@ const align = () => {
const width = content.value!.offsetWidth; const width = content.value!.offsetWidth;
const height = content.value!.offsetHeight; const height = content.value!.offsetHeight;
let left: number; let left = 0;
let top: number; let top = MARGIN;
const x = srcRect.left + (fixed.value ? 0 : window.scrollX); const x = srcRect.left + (fixed.value ? 0 : window.scrollX);
const y = srcRect.top + (fixed.value ? 0 : window.scrollY); const y = srcRect.top + (fixed.value ? 0 : window.scrollY);

View file

@ -35,7 +35,7 @@ defineProps<{
align?: "center" | string; align?: "center" | string;
width?: number; width?: number;
viaKeyboard?: boolean; viaKeyboard?: boolean;
src?: any; src?: HTMLElement | null;
noReturnFocus?; noReturnFocus?;
}>(); }>();

View file

@ -213,7 +213,7 @@ interface VueComponentConstructor<P, E> {
export async function popup<Props, Emits>( export async function popup<Props, Emits>(
component: VueComponentConstructor<Props, Emits>, component: VueComponentConstructor<Props, Emits>,
props: Props & Record<string, unknown>, props: Props & Record<string, unknown>,
events: Partial<NonNullable<Emits>> | Record<string, never> = {}, events: Partial<Emits> = {},
disposeEvent?: string, disposeEvent?: string,
) { ) {
markRaw(component); markRaw(component);
@ -858,7 +858,7 @@ export async function openEmojiPicker(
export function popupMenu( export function popupMenu(
items: MenuItem[] | Ref<MenuItem[]>, items: MenuItem[] | Ref<MenuItem[]>,
src?: HTMLElement, src?: HTMLElement | null,
options?: { options?: {
align?: string; align?: string;
width?: number; width?: number;