You've already forked SmartisanNote.Remake
154 lines
4.6 KiB
Vue
154 lines
4.6 KiB
Vue
<template>
|
||
<ion-page>
|
||
<Header title="文件夹" :onBack="() => window.history.back()" />
|
||
<div class="folder-page-container">
|
||
<div class="search-container">
|
||
<ion-icon :icon="search" class="search-icon"></ion-icon>
|
||
<ion-input placeholder="搜索文件夹..." :value="searchQuery" @ionChange="e => setSearchQuery(e.detail.value)" class="search-input"></ion-input>
|
||
<ion-button v-if="searchQuery.length > 0" fill="clear" @click="() => setSearchQuery('')">
|
||
<ion-icon :icon="closeCircle" class="clear-icon"></ion-icon>
|
||
</ion-button>
|
||
</div>
|
||
</div>
|
||
<ion-content>
|
||
<ion-list class="folder-list">
|
||
<FolderManage
|
||
:allCount="allNotesCount"
|
||
:starredCount="starredNotesCount"
|
||
:trashCount="trashNotesCount"
|
||
:archiveCount="archiveCount"
|
||
:selectedFolder="selectedFolder"
|
||
:onAllClick="() => handleFolderPress('all')"
|
||
:onStarredClick="() => handleFolderPress('starred')"
|
||
:onTrashClick="() => handleFolderPress('trash')"
|
||
:onArchiveClick="() => handleFolderPress('archive')" />
|
||
</ion-list>
|
||
</ion-content>
|
||
</ion-page>
|
||
</template>
|
||
|
||
<script setup>
|
||
import { ref, computed, onMounted } from 'vue'
|
||
import { useRouter } from 'vue-router'
|
||
import { useAppStore } from '../stores/useAppStore'
|
||
import { search, closeCircle } from 'ionicons/icons'
|
||
import FolderManage from '../components/FolderManage.vue'
|
||
import Header from '../components/Header.vue'
|
||
|
||
const store = useAppStore()
|
||
const router = useRouter()
|
||
|
||
// 加载初始数据
|
||
onMounted(() => {
|
||
store.loadData()
|
||
})
|
||
|
||
const searchQuery = ref('')
|
||
const selectedFolder = ref('all')
|
||
|
||
// 计算每个文件夹中的便签数量
|
||
// 遍历所有自定义文件夹,统计每个文件夹中的便签数量
|
||
const foldersWithCount = computed(() => {
|
||
return store.folders.map(folder => {
|
||
const noteCount = store.notes.filter(note => note.folderId === folder.id).length
|
||
return {
|
||
...folder,
|
||
noteCount,
|
||
}
|
||
})
|
||
})
|
||
|
||
// 添加默认文件夹(全部便签、加星便签、回收站)到列表开头
|
||
// 计算全部便签数量
|
||
const allNotesCount = computed(() => store.notes.length)
|
||
// 计算加星便签数量
|
||
const starredNotesCount = computed(() => store.notes.filter(note => note.isStarred).length)
|
||
// 回收站便签数量(暂未实现完整功能)
|
||
const trashNotesCount = 0
|
||
// 归档便签数量(暂未实现完整功能)
|
||
const archiveCount = 0
|
||
|
||
// 合并默认文件夹和自定义文件夹
|
||
const foldersWithAllNotes = computed(() => {
|
||
return [
|
||
{ id: 'all', name: '全部便签', noteCount: allNotesCount.value, createdAt: new Date() },
|
||
{ id: 'starred', name: '加星便签', noteCount: starredNotesCount.value, createdAt: new Date() },
|
||
{ id: 'trash', name: '回收站', noteCount: trashNotesCount, createdAt: new Date() },
|
||
...foldersWithCount.value,
|
||
]
|
||
})
|
||
|
||
const handleFolderPress = folderId => {
|
||
// 更新选中的文件夹状态
|
||
selectedFolder.value = folderId
|
||
// 使用vue-router导航回便签列表页面,并传递文件夹参数
|
||
router.push(`/notes?folder=${folderId}`)
|
||
}
|
||
|
||
// 处理添加文件夹按钮点击事件
|
||
// 在完整实现中,这里会打开文件夹创建对话框
|
||
const handleAddFolder = () => {
|
||
console.log('Add folder pressed')
|
||
}
|
||
|
||
// 处理搜索功能
|
||
// 在完整实现中,这里会根据搜索关键词过滤文件夹
|
||
const handleSearch = () => {
|
||
console.log('Search for:', searchQuery.value)
|
||
}
|
||
|
||
const handleBackPress = () => {
|
||
router.back()
|
||
}
|
||
|
||
// 根据搜索关键词过滤文件夹
|
||
// 将文件夹名称转换为小写进行模糊匹配
|
||
const filteredFolders = computed(() => {
|
||
return foldersWithAllNotes.value.filter(folder => folder.name.toLowerCase().includes(searchQuery.value.toLowerCase()))
|
||
})
|
||
|
||
const setSearchQuery = value => {
|
||
searchQuery.value = value
|
||
}
|
||
</script>
|
||
|
||
<style scoped>
|
||
.folder-page-container {
|
||
padding: 0.625rem;
|
||
background-color: var(--background);
|
||
touch-action: pan-y;
|
||
}
|
||
|
||
.search-container {
|
||
display: flex;
|
||
align-items: center;
|
||
background-color: var(--search-bar-background);
|
||
border-radius: 0.5rem;
|
||
padding: 0 0.625rem;
|
||
}
|
||
|
||
.search-icon {
|
||
font-size: 1.25rem;
|
||
color: var(--text-tertiary);
|
||
}
|
||
|
||
.search-input {
|
||
--padding-start: 0.625rem;
|
||
--padding-end: 0.625rem;
|
||
flex: 1;
|
||
font-size: 1rem;
|
||
color: var(--text-primary);
|
||
}
|
||
|
||
.clear-icon {
|
||
font-size: 1.25rem;
|
||
color: var(--text-tertiary);
|
||
}
|
||
|
||
.folder-list {
|
||
background-color: var(--background);
|
||
padding: 0 1rem;
|
||
--ion-item-background: var(--background);
|
||
}
|
||
</style>
|