import { HStack, VStack, Icon, Text, Badge, Box, Tooltip } from "@hope-ui/solid" import { Motion } from "@motionone/solid" import { useContextMenu } from "solid-contextmenu" import { batch, Show, For, createSignal, onMount, onCleanup, createMemo, } from "solid-js" import { LinkWithPush } from "~/components" import { usePath, useRouter, useUtil, useT } from "~/hooks" import { checkboxOpen, getMainColor, local, OrderBy, selectIndex, selectedObjs, } from "~/store" import { ObjType, StoreObj, Obj } from "~/types" import { bus, formatDate, getFileSize, hoverColor, normalizeStorageClass, } from "~/utils" import { getIconByObj } from "~/utils/icon" import { ItemCheckbox, useSelectWithMouse } from "./helper" import { me } from "~/store" import { getColorWithOpacity } from "~/utils/color" import { pathJoin } from "~/utils/path" interface Label { id: number name: string type: number description: string bg_color: string } export interface Col { name: OrderBy | "tag" textAlign: "left" | "right" w: any } export const cols: Col[] = [ { name: "name", textAlign: "left", w: { "@initial": "calc(100% - 100px)", "@md": "35%" }, }, { name: "size", textAlign: "right", w: { "@initial": "100px", "@md": "30%" }, }, { name: "modified", textAlign: "right", w: { "@initial": 0, "@md": "25%" } }, ] // 添加选中统计组件 const SelectionStats = () => { const selected = selectedObjs const totalSize = createMemo(() => { return selected().reduce((acc, obj) => acc + (obj.size || 0), 0) }) const t = useT() return ( 0}> {t("home.selected")} {selected().length} {t("home.selected_count")} {t("home.total_size")} {getFileSize(totalSize())} ) } export const ListItem = (props: { obj: StoreObj & Obj; index: number }) => { const { isHide } = useUtil() const { refresh } = usePath() if (isHide(props.obj)) { return null } const { setPathAs } = usePath() const { show } = useContextMenu({ id: 1 }) const { pushHref, to, pathname } = useRouter() const { openWithDoubleClick, toggleWithClick, restoreSelectionCache } = useSelectWithMouse() const t = useT() const filenameStyle = () => local["list_item_filename_overflow"] const storageClassKey = createMemo(() => normalizeStorageClass(props.obj.storage_class), ) const storageClassLabel = createMemo(() => { const key = storageClassKey() return key ? t(`home.storage_class.${key}`) : undefined }) const filenameContainerStyle = () => { const style = filenameStyle() if (style === "ellipsis") { return { display: "inline-block", "white-space": "nowrap", overflow: "hidden", "text-overflow": "ellipsis", flex: "1 1 auto", "min-width": 0, } } if (style === "scrollable") { return { display: "inline-block", "white-space": "nowrap", overflow: "hidden", flex: "1 1 auto", "min-width": 0, } } return { display: "block", "white-space": "normal", "word-break": "break-word", "line-height": "1.4", flex: "1 1 auto", "min-width": 0, } } // 构建完整路径 const getFullPath = () => { // 如果obj.path存在且是完整路径(以权限路径开头),直接使用 const userPermissions = me().permissions || [] // if ( // props.obj.path && // userPermissions.some((perm) => props.obj.path?.startsWith(perm.path)) // ) { // return props.obj.path // } // 否则使用当前路径 return pathJoin(pathname(), props.obj.name) } return ( <> { if (!openWithDoubleClick()) return selectIndex(props.index, true, true) to(getFullPath()) }} on:click={(e: MouseEvent) => { e.preventDefault() if (openWithDoubleClick()) return if (e.ctrlKey || e.metaKey || e.shiftKey) return if (!restoreSelectionCache()) return if (toggleWithClick()) return selectIndex(props.index, !props.obj.selected) to(getFullPath()) }} onMouseEnter={() => { setPathAs(props.obj.name, props.obj.is_dir, true) }} onContextMenu={(e: MouseEvent) => { batch(() => { selectIndex(props.index, true, true) }) show(e, { props: props.obj }) }} > { e.stopPropagation() }} on:click={(e: MouseEvent) => { e.stopPropagation() }} checked={props.obj.selected} onChange={(e: any) => { selectIndex(props.index, e.target.checked) }} /> { if (props.obj.type !== ObjType.IMAGE) return if (e.ctrlKey || e.metaKey || e.shiftKey) return if (!restoreSelectionCache()) return bus.emit("gallery", props.obj.name) e.preventDefault() e.stopPropagation() }} />
{ if (el) { onMount(() => { const checkWidth = () => { const parent = el.parentElement if ( parent && el.scrollWidth > parent.clientWidth ) { el.classList.add("should-marquee") } else { el.classList.remove("should-marquee") } } checkWidth() // 监听窗口大小变化,重新检查是否需要滚动 window.addEventListener("resize", checkWidth) onCleanup(() => { window.removeEventListener("resize", checkWidth) }) }) } }} style={{ display: "inline-block", "white-space": "nowrap", "padding-right": "50px", }} > {props.obj.name}
{props.obj.name}
{storageClassLabel()}
{(label: Label) => ( {label.name} )} {getFileSize(props.obj.size)} {formatDate(props.obj.modified)}
{/* 移动端显示 */} {(label: Label) => ( {label.name} )}
) }