初始化提交

This commit is contained in:
2025-10-10 08:13:38 +08:00
commit 0d4c7353f4
1361 changed files with 13945 additions and 0 deletions

View File

@@ -0,0 +1,229 @@
<template>
<div
@click="onPress"
class="folder-item-container"
:class="{ 'folder-item-selected': isSelected, 'folder-item-pressed': isPressed }"
@mousedown="handleMouseDown"
@mouseup="handleMouseUp"
@mouseleave="handleMouseLeave"
>
<div class="folder-item-content">
<!-- Hidden folder icon (matches native implementation) -->
<img
v-if="folderIconSrc"
:src="folderIconSrc"
class="folder-item-icon"
alt="folder icon"
style="visibility: hidden;"
/>
<ion-icon
v-else
:icon="folderIcon"
class="folder-item-icon"
style="visibility: hidden;"
></ion-icon>
<!-- Checkbox for selection (visible when isSelected is true) -->
<img
v-if="isSelected"
src="/assets/icons/drawable-xxhdpi/icon_folder_checked.png"
class="folder-item-checkbox"
alt="selected"
/>
<img
v-else
src="/assets/icons/drawable-xxhdpi/icon_folder_unchecked.png"
class="folder-item-checkbox"
alt="not selected"
/>
<div class="folder-item-text-container">
<div class="folder-item-name">
{{ name }}
</div>
<div class="folder-item-count">
{{ noteCount }} 条便签
</div>
</div>
<!-- Selected indicator (visible when isSelected is true) -->
<img
v-if="isSelected"
src="/assets/icons/drawable-xxhdpi/folder_selected.png"
class="folder-item-selected-icon"
alt="selected"
/>
</div>
</div>
</template>
<script>
import { folder, star, trash, document } from 'ionicons/icons';
export default {
name: 'FolderItem',
props: {
id: {
type: String,
required: true
},
name: {
type: String,
required: true
},
noteCount: {
type: Number,
required: true
},
onPress: {
type: Function,
required: true
},
isSelected: {
type: Boolean,
default: false
}
},
data() {
return {
folder,
star,
trash,
document,
isPressed: false
}
},
computed: {
folderIcon() {
switch (this.id) {
case 'all':
return this.folder;
case 'starred':
return this.star;
case 'trash':
return this.trash;
default:
return this.document;
}
},
folderIconSrc() {
switch (this.id) {
case 'all':
return '/assets/icons/drawable-xxhdpi/sidebar_folder_icon_all.png';
case 'starred':
return '/assets/icons/drawable-xxhdpi/sidebar_folder_icon_favorite.png';
case 'trash':
return '/assets/icons/drawable-xxhdpi/sidebar_folder_icon_trash.png';
default:
return '/assets/icons/drawable-xxhdpi/sidebar_folder_icon_document.png';
}
}
},
methods: {
handleMouseDown() {
this.isPressed = true;
},
handleMouseUp() {
this.isPressed = false;
},
handleMouseLeave() {
this.isPressed = false;
}
}
}
</script>
<style scoped>
.folder-item-container {
position: relative;
min-height: 44px;
background-color: var(--background-card);
cursor: pointer;
overflow: hidden;
}
.folder-item-container.folder-item-selected {
background-color: var(--folder-item-selected);
}
.folder-item-container.folder-item-pressed {
background-color: var(--black-05);
transform: scale(0.99);
}
.folder-item-container.folder-item-pressed::after {
content: '';
position: absolute;
top: 0;
left: 0;
right: 0;
bottom: 0;
background: url('/assets/icons/drawable-xxhdpi/folder_item_pressed_bg.png') repeat;
background-size: 100% 100%;
opacity: 0.5;
pointer-events: none;
transition: opacity 0.2s ease;
}
.folder-item-content {
display: flex;
align-items: center;
width: 100%;
height: 44px;
padding: 0 16px;
position: relative;
}
.folder-item-icon {
width: 30px;
height: 30px;
color: var(--folder-name);
flex-shrink: 0;
margin-left: 1px;
padding-left: 11px;
}
.folder-item-icon[src] {
width: 30px;
height: 30px;
object-fit: contain;
}
.folder-item-checkbox {
width: 30px;
height: 30px;
flex-shrink: 0;
margin-left: 10px;
}
.folder-item-selected-icon {
width: 30px;
height: 30px;
margin-left: auto;
flex-shrink: 0;
margin-right: 0;
}
.folder-item-text-container {
flex: 1;
margin-left: 10px;
margin-right: 6px;
}
.folder-item-name {
font-size: 15px;
font-weight: normal;
color: var(--folder-name);
line-height: 1.2;
overflow: hidden;
text-overflow: ellipsis;
white-space: nowrap;
}
.folder-item-count {
font-size: 12px;
color: var(--folder-count);
line-height: 1.2;
margin-top: 2px;
}
</style>