美化外观
parent
8ebf1216af
commit
33988cbd0a
|
|
@ -71,6 +71,7 @@ watch(() => global.tabList, async () => {
|
|||
<edge-trigger :tabIdx="tabIdx">
|
||||
<a-tabs type="editable-card" v-model:activeKey="tab.key" @edit="(key, act) => onEdit(tabIdx, key, act)">
|
||||
<a-tab-pane v-for="pane, paneIdx in tab.panes" :key="pane.key" :tab="pane.name"
|
||||
class="pane"
|
||||
:force-render="pane.type === 'task-record'">
|
||||
<component :is="compMap[pane.type]" :tabIdx="tabIdx" :paneIdx="paneIdx" v-bind="pane" />
|
||||
</a-tab-pane>
|
||||
|
|
@ -91,4 +92,7 @@ watch(() => global.tabList, async () => {
|
|||
height: 100vh;
|
||||
}
|
||||
}
|
||||
.pane {
|
||||
height: calc(100vh - 40px);
|
||||
}
|
||||
</style>
|
||||
|
|
@ -383,7 +383,8 @@ export function useFilesDisplay (props: Props) {
|
|||
value: (v) => v,
|
||||
text: (v) => '按' + sortMethodMap[v]
|
||||
}
|
||||
const gridSize = 288
|
||||
const gridSize = 272
|
||||
const profileHeight = 64
|
||||
const largeGridSize = gridSize * 2
|
||||
const { width } = useElementSize(stackViewEl)
|
||||
const gridItems = computed(() => {
|
||||
|
|
@ -394,6 +395,19 @@ export function useFilesDisplay (props: Props) {
|
|||
return ~~(w / (viewMode.value === 'grid' ? gridSize : largeGridSize))
|
||||
})
|
||||
|
||||
const itemSize = computed(() => {
|
||||
const mode = viewMode.value
|
||||
if (mode === 'line') {
|
||||
return { first: 80, second: undefined }
|
||||
}
|
||||
const second = (mode === 'grid' ? gridSize : largeGridSize)
|
||||
const first = second + profileHeight
|
||||
return {
|
||||
first,
|
||||
second
|
||||
}
|
||||
})
|
||||
|
||||
const loadNextDirLoading = ref(false)
|
||||
|
||||
|
||||
|
|
@ -451,7 +465,8 @@ export function useFilesDisplay (props: Props) {
|
|||
onScroll,
|
||||
loadNextDir,
|
||||
loadNextDirLoading,
|
||||
canLoadNext
|
||||
canLoadNext,
|
||||
itemSize
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ watch(() => props, () => {
|
|||
|
||||
const { currLocation, currPage, refresh, copyLocation, back, openNext, stack, to } = useLocation(props)
|
||||
const { gridItems, sortMethodConv, moreActionsDropdownShow,
|
||||
sortedFiles, sortMethod, viewMode, gridSize, viewModeMap, largeGridSize,
|
||||
sortedFiles, sortMethod, viewMode, viewModeMap, itemSize,
|
||||
loadNextDir, loadNextDirLoading, canLoadNext,
|
||||
onScroll } = useFilesDisplay(props)
|
||||
const { onDrop, onFileDragStart, multiSelectedIdxs } = useFileTransfer(props)
|
||||
|
|
@ -50,9 +50,9 @@ const { previewIdx, onPreviewVisibleChange, previewing, previewImgMove, canPrevi
|
|||
<AModal v-model:visible="showGenInfo" width="50vw">
|
||||
<ASkeleton active :loading="!q.isIdle">
|
||||
<pre style="width: 100%; word-break: break-all;white-space: pre-line;" @dblclick="copy2clipboard(imageGenInfo)">
|
||||
双击复制
|
||||
{{ imageGenInfo }}
|
||||
</pre>
|
||||
双击复制
|
||||
{{ imageGenInfo }}
|
||||
</pre>
|
||||
</ASkeleton>
|
||||
</AModal>
|
||||
<div class="location-bar">
|
||||
|
|
@ -114,24 +114,43 @@ const { previewIdx, onPreviewVisibleChange, previewing, previewImgMove, canPrevi
|
|||
</div>
|
||||
<div v-if="currPage" class="view">
|
||||
<RecycleScroller class="file-list" :items="sortedFiles" :prerender="10" ref="scroller" @scroll="onScroll"
|
||||
:item-size="viewMode === 'line' ? 80 : (viewMode === 'grid' ? gridSize : largeGridSize)" key-field="fullpath"
|
||||
:gridItems="gridItems">
|
||||
:item-size="itemSize.first" key-field="fullpath" :item-secondary-size="itemSize.second" :gridItems="gridItems">
|
||||
<template v-slot="{ item: file, index: idx }">
|
||||
<a-dropdown :trigger="['contextmenu']">
|
||||
<li class="file"
|
||||
:class="{ clickable: file.type === 'dir', selected: multiSelectedIdxs.includes(idx), grid: viewMode === 'grid', 'large-grid': viewMode === 'large-size-grid' }"
|
||||
:class="{ clickable: file.type === 'dir', selected: multiSelectedIdxs.includes(idx), grid: viewMode === 'grid' || viewMode === 'large-size-grid', 'large-grid': viewMode === 'large-size-grid' }"
|
||||
:key="file.name" draggable="true" @dragstart="onFileDragStart($event, idx)"
|
||||
@click.capture="onFileItemClick($event, file)">
|
||||
<a-image ref="dd" :key="file.fullpath" :class="`idx-${idx}`"
|
||||
v-if="props.target === 'local' && viewMode !== 'line' && isImageFile(file.name)"
|
||||
:src="global.enableThumbnail ? toImageThumbnailUrl(file, viewMode === 'grid' ? void 0 : '512,512') : toRawFileUrl(file)"
|
||||
:fallback="fallbackImage"
|
||||
:preview="{ src: sortedFiles[previewIdx] ? toRawFileUrl(sortedFiles[previewIdx]) : '', onVisibleChange: onPreviewVisibleChange }">
|
||||
</a-image>
|
||||
<div v-if="viewMode !== 'line'">
|
||||
<a-image :key="file.fullpath" :class="`idx-${idx}`"
|
||||
v-if="props.target === 'local' && isImageFile(file.name)"
|
||||
:src="global.enableThumbnail ? toImageThumbnailUrl(file, viewMode === 'grid' ? void 0 : '512,512') : toRawFileUrl(file)"
|
||||
:fallback="fallbackImage"
|
||||
:preview="{ src: sortedFiles[previewIdx] ? toRawFileUrl(sortedFiles[previewIdx]) : '', onVisibleChange: onPreviewVisibleChange }">
|
||||
</a-image>
|
||||
<div v-else class="preview-icon-wrap">
|
||||
|
||||
<file-outlined class="icon center" v-if="file.type === 'file'" />
|
||||
<folder-open-outlined class="icon center" v-else />
|
||||
</div>
|
||||
<div class="profile">
|
||||
<div class="name">
|
||||
{{ file.name }}
|
||||
</div>
|
||||
<div class="basic-info">
|
||||
<div>
|
||||
{{ file.size }}
|
||||
</div>
|
||||
<div>
|
||||
{{ file.date }}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<template v-else>
|
||||
<file-outlined class="icon" v-if="file.type === 'file'" />
|
||||
<folder-open-outlined class="icon" v-else />
|
||||
<div class="name">
|
||||
<div class="name line-clamp-1">
|
||||
{{ file.name }}
|
||||
</div>
|
||||
<div class="basic-info">
|
||||
|
|
@ -214,10 +233,13 @@ const { previewIdx, onPreviewVisibleChange, previewing, previewImgMove, canPrevi
|
|||
|
||||
.container {
|
||||
height: 100%;
|
||||
background: var(--zp-secondary-background);
|
||||
}
|
||||
|
||||
.location-bar {
|
||||
margin: 0 16px;
|
||||
padding: 4px 16px;
|
||||
background: var(--zp-primary-background);
|
||||
border-bottom: 1px solid var(--zp-border);
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: space-between;
|
||||
|
|
@ -235,6 +257,12 @@ const { previewIdx, onPreviewVisibleChange, previewing, previewImgMove, canPrevi
|
|||
}
|
||||
}
|
||||
|
||||
.center {
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.view {
|
||||
padding: 8px;
|
||||
height: calc(100vh - 96px);
|
||||
|
|
@ -252,71 +280,68 @@ const { previewIdx, onPreviewVisibleChange, previewing, previewImgMove, canPrevi
|
|||
align-items: center;
|
||||
background: var(--zp-primary-background);
|
||||
border-radius: 8px;
|
||||
box-shadow: 0 0 4px #ccc;
|
||||
box-shadow: 0 0 4px var(--zp-secondary-variant-background);
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
|
||||
&.grid {
|
||||
padding: 8px;
|
||||
height: 256px;
|
||||
width: 256px;
|
||||
padding: 0;
|
||||
display: inline-block;
|
||||
box-sizing: content-box;
|
||||
box-shadow: unset;
|
||||
|
||||
|
||||
background-color: var(--zp-secondary-background);
|
||||
|
||||
:deep() {
|
||||
.icon {
|
||||
font-size: 6em;
|
||||
margin-top: 16px;
|
||||
font-size: 8em;
|
||||
}
|
||||
|
||||
.name {
|
||||
margin: 16px 0;
|
||||
|
||||
.profile {
|
||||
padding: 0 4px;
|
||||
|
||||
.name {
|
||||
font-weight: 500;
|
||||
padding: 0;
|
||||
}
|
||||
|
||||
.basic-info {
|
||||
display: flex;
|
||||
justify-content: space-between;
|
||||
flex-direction: row;
|
||||
margin: 0;
|
||||
font-size: .7em;
|
||||
}
|
||||
}
|
||||
|
||||
.basic-info {
|
||||
position: absolute;
|
||||
bottom: 16px;
|
||||
right: 16px;
|
||||
.ant-image,
|
||||
.preview-icon-wrap {
|
||||
border: 1px solid var(--zp-secondary);
|
||||
background-color: var(--zp-secondary-variant-background);
|
||||
border-radius: 8px;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
img {
|
||||
img,
|
||||
.preview-icon-wrap>[role="img"] {
|
||||
height: 256px;
|
||||
width: 256px;
|
||||
object-fit: contain;
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
&.large-grid {
|
||||
padding: 8px;
|
||||
height: 512px;
|
||||
width: 512px;
|
||||
margin: 16px;
|
||||
display: inline-block;
|
||||
box-sizing: content-box;
|
||||
|
||||
|
||||
:deep() {
|
||||
.icon {
|
||||
font-size: 6em;
|
||||
margin-top: 16px;
|
||||
}
|
||||
|
||||
.name {
|
||||
margin: 16px 0;
|
||||
}
|
||||
|
||||
.basic-info {
|
||||
position: absolute;
|
||||
bottom: 16px;
|
||||
right: 16px;
|
||||
}
|
||||
|
||||
img {
|
||||
img,
|
||||
.preview-icon-wrap>[role="img"] {
|
||||
height: 512px;
|
||||
width: 512px;
|
||||
object-fit: contain;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
$primary-color: #1890ff;
|
||||
$primary-color: #d03f0a;
|
||||
$danger-color: #fa114f;
|
||||
$info-color: #17a2b8;
|
||||
$success-color: #28a745;
|
||||
|
|
@ -63,7 +63,7 @@ $success-color: #28a745;
|
|||
--zp-tertiary-background: var(--zp-white);
|
||||
--zp-secondary-variant-background: var(--zp-grey7);
|
||||
// 边框颜色
|
||||
--zp-border: var(--zp-grey4);
|
||||
--zp-border: var(--zp-grey20);
|
||||
@media (prefers-color-scheme: dark) {
|
||||
--zp-primary: var(--zp-grey20);
|
||||
--zp-secondary: var(--zp-grey60);
|
||||
|
|
@ -115,4 +115,23 @@ body {
|
|||
}
|
||||
background: var(--zp-primary-background);
|
||||
color: var(--zp-primary);
|
||||
.ant-tabs > div.ant-tabs-nav {
|
||||
margin: 0;
|
||||
}
|
||||
}
|
||||
|
||||
@mixin line-clamp($n: 1) {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: $n;
|
||||
overflow: hidden;
|
||||
}
|
||||
.line-clamp-1 {
|
||||
@include line-clamp(1);
|
||||
}
|
||||
.line-clamp-2 {
|
||||
@include line-clamp(2);
|
||||
}
|
||||
.line-clamp-3 {
|
||||
@include line-clamp(3);
|
||||
}
|
||||
|
|
@ -0,0 +1,7 @@
|
|||
|
||||
@mixin line-clamp($n: 1) {
|
||||
display: -webkit-box;
|
||||
-webkit-box-orient: vertical;
|
||||
-webkit-line-clamp: $n;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
|
@ -12,13 +12,18 @@ export default defineConfig({
|
|||
preprocessorOptions: {
|
||||
modules: true,
|
||||
less: {
|
||||
// #d03f0a// https://github.com/vueComponent/ant-design-vue/blob/main/components/style/themes/default.less
|
||||
modifyVars: {
|
||||
'primary-color': '#d03f0a',
|
||||
'link-color': '#d03f0a',
|
||||
},
|
||||
javascriptEnabled: true,
|
||||
}
|
||||
}
|
||||
},
|
||||
plugins: [vue(),
|
||||
Components({
|
||||
resolvers: [AntDesignVueResolver({ importStyle: 'css' })],
|
||||
resolvers: [AntDesignVueResolver({ importStyle: 'less' })],
|
||||
}),],
|
||||
resolve: {
|
||||
alias: {
|
||||
|
|
|
|||
Loading…
Reference in New Issue