You've already forked SmartisanNote.Remake
还原了搜索栏布局、样式;
还原了文件夹管理布局、样式; 还原了头部布局、样式;
This commit is contained in:
@@ -38,8 +38,8 @@
|
|||||||
--note-star: #ffffdd33; /* Star/favorite color (updated to match original) */
|
--note-star: #ffffdd33; /* Star/favorite color (updated to match original) */
|
||||||
|
|
||||||
/* Folder colors */
|
/* Folder colors */
|
||||||
--folder-name: #99000000; /* Folder name color (60% black) */
|
--folder-name: #9b9b9b; /* Folder name color (60% black) */
|
||||||
--folder-count: #4c000000; /* Folder item count color (30% black) */
|
--folder-count: #b4b4b4; /* Folder item count color (30% black) */
|
||||||
--folder-item-selected: #f5f5f5; /* Folder item selected background color */
|
--folder-item-selected: #f5f5f5; /* Folder item selected background color */
|
||||||
|
|
||||||
/* Button colors - Based on Smartisan's button styles */
|
/* Button colors - Based on Smartisan's button styles */
|
||||||
|
|||||||
BIN
public/assets/icons/drawable-xxhdpi/btn_add_folder.png
Normal file
BIN
public/assets/icons/drawable-xxhdpi/btn_add_folder.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 6.9 KiB |
BIN
public/assets/icons/drawable-xxhdpi/btn_edit_folder.png
Normal file
BIN
public/assets/icons/drawable-xxhdpi/btn_edit_folder.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 9.0 KiB |
Binary file not shown.
|
Before Width: | Height: | Size: 107 KiB After Width: | Height: | Size: 119 KiB |
@@ -1,221 +1,77 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div @click="onPress" class="code-fun-flex-row code-fun-items-center code-fun-relative folder-item">
|
||||||
@click="onPress"
|
<img class="folder-icon" :src="iconSrc" />
|
||||||
class="folder-item-container"
|
<span class="folder-name">{{ name }}</span>
|
||||||
:class="{ 'folder-item-selected': isSelected, 'folder-item-pressed': isPressed }"
|
<span class="folder-count">{{ noteCount }}</span>
|
||||||
@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>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed } from 'vue';
|
import { computed } from 'vue'
|
||||||
import { folder, star, trash, document } from 'ionicons/icons';
|
|
||||||
|
|
||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
id: {
|
id: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
name: {
|
name: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
noteCount: {
|
noteCount: {
|
||||||
type: Number,
|
type: Number,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
onPress: {
|
onPress: {
|
||||||
type: Function,
|
type: Function,
|
||||||
required: true
|
required: true,
|
||||||
},
|
},
|
||||||
isSelected: {
|
isSelected: {
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false
|
default: false,
|
||||||
}
|
},
|
||||||
});
|
})
|
||||||
|
|
||||||
const isPressed = ref(false);
|
const iconSrc = computed(() => {
|
||||||
|
|
||||||
const folderIcon = computed(() => {
|
|
||||||
switch (props.id) {
|
switch (props.id) {
|
||||||
case 'all':
|
case 'all':
|
||||||
return folder;
|
return 'assets/icons/drawable-xxhdpi/icon_folder_all.png'
|
||||||
case 'starred':
|
case 'starred':
|
||||||
return star;
|
return 'assets/icons/drawable-xxhdpi/icon_folder_favorite.png'
|
||||||
case 'trash':
|
case 'trash':
|
||||||
return trash;
|
return 'assets/icons/drawable-xxhdpi/icon_folder_trash.png'
|
||||||
|
case 'archive':
|
||||||
|
return 'assets/icons/drawable-xxhdpi/icon_folder_document.png'
|
||||||
default:
|
default:
|
||||||
return document;
|
return 'assets/icons/drawable-xxhdpi/icon_folder_document.png'
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
const folderIconSrc = computed(() => {
|
|
||||||
switch (props.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';
|
|
||||||
}
|
|
||||||
});
|
|
||||||
|
|
||||||
const handleMouseDown = () => {
|
|
||||||
isPressed.value = true;
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleMouseUp = () => {
|
|
||||||
isPressed.value = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
const handleMouseLeave = () => {
|
|
||||||
isPressed.value = false;
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style scoped>
|
<style scoped>
|
||||||
.folder-item-container {
|
.folder-item {
|
||||||
position: relative;
|
padding: 0.3rem 0;
|
||||||
min-height: 44px;
|
background-color: #00000000;
|
||||||
background-color: var(--background-card);
|
|
||||||
cursor: pointer;
|
|
||||||
overflow: hidden;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.folder-item-container.folder-item-selected {
|
.folder-icon {
|
||||||
background-color: var(--folder-item-selected);
|
width: 1.8rem;
|
||||||
}
|
height: 1.8rem;
|
||||||
|
|
||||||
.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;
|
flex-shrink: 0;
|
||||||
margin-left: 1px;
|
margin-inline: 0.3rem;
|
||||||
padding-left: 11px;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
.folder-item-icon[src] {
|
.folder-name {
|
||||||
width: 30px;
|
font-size: 0.9rem;
|
||||||
height: 30px;
|
line-height: 1.52rem;
|
||||||
object-fit: contain;
|
color: #9b9b9b;
|
||||||
}
|
}
|
||||||
|
|
||||||
.folder-item-checkbox {
|
.folder-count {
|
||||||
width: 30px;
|
font-size: 0.8rem;
|
||||||
height: 30px;
|
line-height: 1.16rem;
|
||||||
flex-shrink: 0;
|
margin-left: 0.7rem;
|
||||||
margin-left: 10px;
|
margin-top: 0.2rem;
|
||||||
}
|
color: #b8b8b8;
|
||||||
|
|
||||||
.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>
|
</style>
|
||||||
135
src/components/FolderManage.vue
Normal file
135
src/components/FolderManage.vue
Normal file
@@ -0,0 +1,135 @@
|
|||||||
|
<template>
|
||||||
|
<div class="code-fun-flex-col page">
|
||||||
|
<!-- 全部便签文件夹项 -->
|
||||||
|
<FolderItem id="all" name="全部便签" :noteCount="allCount" :isSelected="selectedFolder === 'all'" :onPress="handleAllClick" />
|
||||||
|
|
||||||
|
<!-- 加星便签文件夹项 -->
|
||||||
|
<FolderItem id="starred" name="加星便签" :noteCount="starredCount" :isSelected="selectedFolder === 'starred'" :onPress="handleStarredClick" />
|
||||||
|
|
||||||
|
<!-- 回收站文件夹项 -->
|
||||||
|
<FolderItem id="trash" name="回收站" :noteCount="trashCount" :isSelected="selectedFolder === 'trash'" :onPress="handleTrashClick" />
|
||||||
|
|
||||||
|
<!-- 同步信息区域 -->
|
||||||
|
<div class="code-fun-flex-col code-fun-justify-start section_7">
|
||||||
|
<div class="code-fun-flex-row code-fun-justify-between code-fun-items-center section_8">
|
||||||
|
<div class="code-fun-flex-row code-fun-items-center">
|
||||||
|
<img class="code-fun-shrink-0 image_7" :src="`assets/icons/drawable-xxhdpi/btn_edit_folder.png`" />
|
||||||
|
<span class="text_11 code-fun-ml-10">上次同步:{{ lastSyncTime }}</span>
|
||||||
|
</div>
|
||||||
|
<div class="code-fun-flex-row code-fun-items-center">
|
||||||
|
<img class="image_8 code-fun-ml-12" :src="`assets/icons/drawable-xxhdpi/btn_add_folder.png`" @click="handleAddFolder" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { computed } from 'vue'
|
||||||
|
import FolderItem from './FolderItem.vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
allCount: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
starredCount: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
trashCount: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
archiveCount: {
|
||||||
|
type: Number,
|
||||||
|
default: 0,
|
||||||
|
},
|
||||||
|
selectedFolder: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
lastSyncTime: {
|
||||||
|
type: String,
|
||||||
|
default: '10/10上午9:28',
|
||||||
|
},
|
||||||
|
onAllClick: {
|
||||||
|
type: Function,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
onStarredClick: {
|
||||||
|
type: Function,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
onTrashClick: {
|
||||||
|
type: Function,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
onArchiveClick: {
|
||||||
|
type: Function,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
onAddFolder: {
|
||||||
|
type: Function,
|
||||||
|
default: null,
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const handleAllClick = () => {
|
||||||
|
if (props.onAllClick) {
|
||||||
|
props.onAllClick()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleStarredClick = () => {
|
||||||
|
if (props.onStarredClick) {
|
||||||
|
props.onStarredClick()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleTrashClick = () => {
|
||||||
|
if (props.onTrashClick) {
|
||||||
|
props.onTrashClick()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleArchiveClick = () => {
|
||||||
|
if (props.onArchiveClick) {
|
||||||
|
props.onArchiveClick()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleAddFolder = event => {
|
||||||
|
// 阻止事件冒泡到父元素
|
||||||
|
event.stopPropagation()
|
||||||
|
if (props.onAddFolder) {
|
||||||
|
props.onAddFolder()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.page {
|
||||||
|
.section_7 {
|
||||||
|
margin-top: 2rem;
|
||||||
|
background-color: #00000000;
|
||||||
|
.section_8 {
|
||||||
|
padding: 0.29rem 0.92rem;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
border: solid 0.063rem #f0ece7;
|
||||||
|
.image_7,
|
||||||
|
.image_8 {
|
||||||
|
border-radius: 0.63rem;
|
||||||
|
width: 2rem;
|
||||||
|
height: 2rem;
|
||||||
|
object-fit: contain;
|
||||||
|
}
|
||||||
|
.text_11 {
|
||||||
|
color: #cacaca;
|
||||||
|
font-size: 0.7rem;
|
||||||
|
line-height: 1.16rem;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -1,22 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="code-fun-flex-row code-fun-items-center component">
|
<div class="code-fun-flex-row code-fun-items-center component">
|
||||||
<!-- 左侧图标 -->
|
<!-- 左侧图标 -->
|
||||||
<img v-if="leftType == 'settings'" class="left-icon" src="/assets/icons/drawable-xxhdpi/btn_settings.png" @click="handleLeftAction" />
|
<img class="left-icon" :src="leftIconSource" @click="handleLeftAction" />
|
||||||
<img v-else class="left-icon" src="/assets/icons/drawable-xxhdpi/btn_back.png" @click="handleLeftAction" />
|
|
||||||
|
|
||||||
<!-- 标题区域 -->
|
<!-- 标题区域 -->
|
||||||
<div class="title-container" @click="handleTitlePress" v-if="leftType == 'settings'">
|
<div class="title-container" @click="handleTitlePress">
|
||||||
<span class="text">{{ title }}</span>
|
<span class="text">{{ title }}</span>
|
||||||
<!-- 文件夹展开图标 -->
|
<!-- 文件夹展开图标 -->
|
||||||
<img class="folder-icon" :src="folderExpanded ? '/assets/icons/drawable-xxhdpi/folder_title_arrow_pressed.png' : '/assets/icons/drawable-xxhdpi/folder_title_arrow_normal.png'" @click.stop="handleFolderToggle" />
|
<img v-if="showFolderIcon" class="folder-icon" :src="folderExpanded ? '/assets/icons/drawable-xxhdpi/folder_title_arrow_pressed.png' : '/assets/icons/drawable-xxhdpi/folder_title_arrow_normal.png'" @click.stop="handleFolderToggle" />
|
||||||
</div>
|
|
||||||
<div class="title-container" v-else>
|
|
||||||
<span class="text">{{ title }}</span>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 右侧操作按钮 -->
|
<!-- 右侧操作按钮 -->
|
||||||
<img v-if="actionIcon === 'create'" class="image_4" src="/assets/icons/drawable-xxhdpi/btn_create.png" @click="handleAction" />
|
<img v-if="actionIcon === 'create'" class="image_4" src="/assets/icons/drawable-xxhdpi/btn_create.png" @click="handleAction" />
|
||||||
<i class="image_4" v-else></i>
|
<div v-else class="image_4-placeholder"></div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@@ -77,33 +73,14 @@ const folderExpanded = computed(() => {
|
|||||||
return props.isFolderExpanded !== undefined ? props.isFolderExpanded : localFolderExpanded.value
|
return props.isFolderExpanded !== undefined ? props.isFolderExpanded : localFolderExpanded.value
|
||||||
})
|
})
|
||||||
|
|
||||||
const actionIconSource = computed(() => {
|
const showFolderIcon = computed(() => {
|
||||||
// 根据actionIcon属性返回对应的图标路径
|
// 只有当leftType为settings且有onFolderToggle回调时才显示文件夹图标
|
||||||
switch (props.actionIcon) {
|
return props.leftType === 'settings' && props.onFolderToggle
|
||||||
case 'settings':
|
|
||||||
return '/assets/icons/drawable-xxhdpi/btn_settings.png'
|
|
||||||
case 'create':
|
|
||||||
return '/assets/icons/drawable-xxhdpi/btn_create.png'
|
|
||||||
default:
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const leftIconSource = computed(() => {
|
const leftIconSource = computed(() => {
|
||||||
// 根据leftIcon属性返回对应的图标路径
|
// 根据leftType属性返回对应的图标路径
|
||||||
switch (props.leftIcon) {
|
return props.leftType === 'settings' ? '/assets/icons/drawable-xxhdpi/btn_settings.png' : '/assets/icons/drawable-xxhdpi/btn_back.png'
|
||||||
case 'folder':
|
|
||||||
// 文件夹图标根据展开状态切换
|
|
||||||
return folderExpanded.value ? '/assets/icons/drawable-xxhdpi/folder_title_arrow_pressed.png' : '/assets/icons/drawable-xxhdpi/folder_title_arrow_normal.png'
|
|
||||||
case 'back':
|
|
||||||
// 返回图标
|
|
||||||
return '/assets/icons/drawable-xxhdpi/btn_back.png'
|
|
||||||
case 'settings':
|
|
||||||
// 设置图标
|
|
||||||
return '/assets/icons/drawable-xxhdpi/btn_settings.png'
|
|
||||||
default:
|
|
||||||
return null
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
const handleFolderToggle = () => {
|
const handleFolderToggle = () => {
|
||||||
@@ -146,10 +123,10 @@ const handleTitlePress = () => {
|
|||||||
|
|
||||||
<style scoped lang="less">
|
<style scoped lang="less">
|
||||||
.component {
|
.component {
|
||||||
padding: 2rem 0.72rem 0.5rem 0.72rem;
|
padding: 2rem 0.72rem 0.5rem;
|
||||||
background-color: #00000000;
|
background-color: #00000000;
|
||||||
background-image: url(https://codefun-proj-user-res-1256085488.cos.ap-guangzhou.myqcloud.com/686f20ecd54496f19f54e801/68e862ab9520a30011f388ff/17600644443142372133.png);
|
background-image: url(assets/icons/drawable-xxhdpi/action_bar_default.png);
|
||||||
background-size: cover;
|
background-size: 100% 100%;
|
||||||
background-position: 0% 0%;
|
background-position: 0% 0%;
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@@ -162,6 +139,11 @@ const handleTitlePress = () => {
|
|||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.image_4-placeholder {
|
||||||
|
width: 1.7rem;
|
||||||
|
height: 1.7rem;
|
||||||
|
}
|
||||||
|
|
||||||
.title-container {
|
.title-container {
|
||||||
display: flex;
|
display: flex;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
|||||||
104
src/components/searchBar.vue
Normal file
104
src/components/searchBar.vue
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
<template>
|
||||||
|
<div class="code-fun-flex-col code-fun-justify-start section_3">
|
||||||
|
<div class="view">
|
||||||
|
<div class="image-wrapper">
|
||||||
|
<!-- 搜索图标 -->
|
||||||
|
<img class="image_7" :src="`assets/icons/drawable-xxhdpi/search_bar_left_icon.png`" />
|
||||||
|
<!-- 搜索输入框 -->
|
||||||
|
<input ref="searchInput" type="input" placeholder="搜索便签..." :value="modelValue" @input="handleInput" @keydown.enter="handleSearch" @focus="handleFocus" @blur="handleBlur" />
|
||||||
|
<!-- 清除按钮 -->
|
||||||
|
<img v-if="modelValue && modelValue.length > 0" class="clear-button" :src="`assets/icons/drawable-xxhdpi/search_clear_normal.png`" @click="handleClear" />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup>
|
||||||
|
import { ref } from 'vue'
|
||||||
|
|
||||||
|
const props = defineProps({
|
||||||
|
modelValue: {
|
||||||
|
type: String,
|
||||||
|
default: '',
|
||||||
|
},
|
||||||
|
})
|
||||||
|
|
||||||
|
const emit = defineEmits(['update:modelValue', 'search', 'clear', 'focus', 'blur'])
|
||||||
|
|
||||||
|
const searchInput = ref(null)
|
||||||
|
|
||||||
|
const handleInput = event => {
|
||||||
|
emit('update:modelValue', event.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleSearch = event => {
|
||||||
|
emit('search', event.target.value)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleClear = () => {
|
||||||
|
emit('update:modelValue', '')
|
||||||
|
emit('clear')
|
||||||
|
if (searchInput.value) {
|
||||||
|
searchInput.value.focus()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleFocus = event => {
|
||||||
|
emit('focus', event)
|
||||||
|
}
|
||||||
|
|
||||||
|
const handleBlur = event => {
|
||||||
|
emit('blur', event)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 暴露方法给父组件
|
||||||
|
defineExpose({
|
||||||
|
focus: () => {
|
||||||
|
if (searchInput.value) {
|
||||||
|
searchInput.value.focus()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
blur: () => {
|
||||||
|
if (searchInput.value) {
|
||||||
|
searchInput.value.blur()
|
||||||
|
}
|
||||||
|
},
|
||||||
|
})
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.section_3 {
|
||||||
|
.view {
|
||||||
|
.image-wrapper {
|
||||||
|
position: relative;
|
||||||
|
padding: 0.25rem 0.5rem;
|
||||||
|
border-radius: 2rem;
|
||||||
|
background: #f6f9fa;
|
||||||
|
border: 1px solid #ccb8a3;
|
||||||
|
display: flex;
|
||||||
|
flex-direction: row;
|
||||||
|
align-items: center;
|
||||||
|
|
||||||
|
.image_7,
|
||||||
|
.clear-button {
|
||||||
|
width: 1.2rem;
|
||||||
|
height: 1.2rem;
|
||||||
|
object-fit: contain;
|
||||||
|
margin-right: 0.1rem;
|
||||||
|
}
|
||||||
|
|
||||||
|
input {
|
||||||
|
flex: 1;
|
||||||
|
height: 1.2rem;
|
||||||
|
line-height: 1.2rem;
|
||||||
|
background: transparent;
|
||||||
|
border: none;
|
||||||
|
outline: none;
|
||||||
|
font-size: 0.75rem;
|
||||||
|
color: #333;
|
||||||
|
padding: 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
||||||
@@ -24,14 +24,16 @@
|
|||||||
</div>
|
</div>
|
||||||
<ion-content>
|
<ion-content>
|
||||||
<ion-list style="background-color: var(--background); padding: 0 16px; --ion-item-background: var(--background)">
|
<ion-list style="background-color: var(--background); padding: 0 16px; --ion-item-background: var(--background)">
|
||||||
<FolderItem
|
<FolderManage
|
||||||
v-for="folder in filteredFolders"
|
:allCount="allNotesCount"
|
||||||
:key="folder.id"
|
:starredCount="starredNotesCount"
|
||||||
:id="folder.id"
|
:trashCount="trashNotesCount"
|
||||||
:name="folder.name"
|
:archiveCount="archiveCount"
|
||||||
:noteCount="folder.noteCount"
|
:selectedFolder="selectedFolder"
|
||||||
:onPress="() => handleFolderPress(folder.id)"
|
:onAllClick="() => handleFolderPress('all')"
|
||||||
:isSelected="folder.id === selectedFolder"
|
:onStarredClick="() => handleFolderPress('starred')"
|
||||||
|
:onTrashClick="() => handleFolderPress('trash')"
|
||||||
|
:onArchiveClick="() => handleFolderPress('archive')"
|
||||||
/>
|
/>
|
||||||
</ion-list>
|
</ion-list>
|
||||||
</ion-content>
|
</ion-content>
|
||||||
@@ -42,7 +44,7 @@
|
|||||||
import { ref, computed, onMounted } from 'vue';
|
import { ref, computed, onMounted } from 'vue';
|
||||||
import { useAppStore } from '../stores/useAppStore';
|
import { useAppStore } from '../stores/useAppStore';
|
||||||
import { search, closeCircle } from 'ionicons/icons';
|
import { search, closeCircle } from 'ionicons/icons';
|
||||||
import FolderItem from '../components/FolderItem.vue';
|
import FolderManage from '../components/FolderManage.vue';
|
||||||
import Header from '../components/Header.vue';
|
import Header from '../components/Header.vue';
|
||||||
|
|
||||||
const store = useAppStore();
|
const store = useAppStore();
|
||||||
@@ -71,6 +73,7 @@ const allNotesCount = computed(() => store.notes.length);
|
|||||||
const starredNotesCount = computed(() => store.notes.filter(note => note.isStarred).length);
|
const starredNotesCount = computed(() => store.notes.filter(note => note.isStarred).length);
|
||||||
// Assuming we have a way to track deleted notes in the future
|
// Assuming we have a way to track deleted notes in the future
|
||||||
const trashNotesCount = 0;
|
const trashNotesCount = 0;
|
||||||
|
const archiveCount = 0;
|
||||||
|
|
||||||
const foldersWithAllNotes = computed(() => {
|
const foldersWithAllNotes = computed(() => {
|
||||||
return [
|
return [
|
||||||
|
|||||||
@@ -1,109 +1,60 @@
|
|||||||
<template>
|
<template>
|
||||||
<ion-page>
|
<ion-app>
|
||||||
<Header
|
<div class="container">
|
||||||
:title="headerTitle"
|
<Header :title="headerTitle" :onAction="handleAddNote" actionIcon="create" leftType="settings" :onLeftAction="handleSettingsPress" :onFolderToggle="handleFolderToggle" :isFolderExpanded="isFolderExpanded" :onTitlePress="handleFolderToggle" />
|
||||||
:onAction="handleAddNote"
|
|
||||||
actionIcon="create"
|
|
||||||
leftType="settings"
|
|
||||||
:onLeftAction="handleSettingsPress"
|
|
||||||
:onFolderToggle="handleFolderToggle"
|
|
||||||
:isFolderExpanded="isFolderExpanded"
|
|
||||||
:onTitlePress="handleFolderToggle"
|
|
||||||
/>
|
|
||||||
|
|
||||||
<!-- 悬浮文件夹列表 - 使用绝对定位实现 -->
|
<!-- 悬浮文件夹列表 - 使用绝对定位实现 -->
|
||||||
<div
|
<div
|
||||||
v-if="isFolderExpanded"
|
v-if="isFolderExpanded"
|
||||||
style="position: absolute; top: 50px; left: 10%; right: 10%; z-index: 1000; background-color: var(--background-card); border-radius: 8px; box-shadow: 0 2px 4px var(--shadow); border: 1px solid var(--border); overflow: hidden"
|
style="position: absolute; top: 50px; left: 10%; right: 10%; z-index: 1000; background-color: var(--background-card); border-radius: 8px; box-shadow: 0 2px 4px var(--shadow); border: 1px solid #f0ece7; overflow: hidden">
|
||||||
>
|
<FolderManage
|
||||||
<FolderItem
|
:allCount="notes.length"
|
||||||
id="all"
|
:starredCount="starredNotesCount"
|
||||||
name="全部便签"
|
:trashCount="0"
|
||||||
:noteCount="notes.length"
|
:archiveCount="0"
|
||||||
:isSelected="currentFolder === 'all'"
|
:selectedFolder="currentFolder"
|
||||||
:onPress="() => {
|
:onAllClick="
|
||||||
setCurrentFolder('all');
|
() => {
|
||||||
setIsFolderExpanded(false);
|
setCurrentFolder('all')
|
||||||
}"
|
setIsFolderExpanded(false)
|
||||||
/>
|
}
|
||||||
<FolderItem
|
"
|
||||||
id="starred"
|
:onStarredClick="
|
||||||
name="加星便签"
|
() => {
|
||||||
:noteCount="starredNotesCount"
|
setCurrentFolder('starred')
|
||||||
:isSelected="currentFolder === 'starred'"
|
setIsFolderExpanded(false)
|
||||||
:onPress="() => {
|
}
|
||||||
setCurrentFolder('starred');
|
"
|
||||||
setIsFolderExpanded(false);
|
:onTrashClick="
|
||||||
}"
|
() => {
|
||||||
/>
|
setCurrentFolder('trash')
|
||||||
<FolderItem
|
setIsFolderExpanded(false)
|
||||||
id="trash"
|
}
|
||||||
name="回收站"
|
" />
|
||||||
:noteCount="0"
|
|
||||||
:isSelected="currentFolder === 'trash'"
|
|
||||||
:onPress="() => {
|
|
||||||
setCurrentFolder('trash');
|
|
||||||
setIsFolderExpanded(false);
|
|
||||||
}"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="flex-direction: row; align-items: center; padding: 8px 16px; background-color: var(--background-card); border-bottom: 1px solid var(--border)">
|
<div style="padding: 0.8rem 0.5rem">
|
||||||
<div style="flex: 1; flex-direction: row; align-items: center; background-color: var(--background-card); height: 36px; padding: 0 8px; padding-vertical: 0">
|
<SearchBar v-model="searchQuery" @search="handleSearch" @clear="handleClearSearch" @focus="handleSearchFocus" @blur="handleSearchBlur" />
|
||||||
<div style="flex: 1; flex-direction: row; align-items: center; background-color: #f0f0f0; border-radius: 4; height: 36px; padding: 0 8px; padding-vertical: 0">
|
|
||||||
<img :src="'/assets/icons/drawable-xxhdpi/search_bar_left_icon.png'" style="width: 20px; height: 20px; tint-color: var(--text-tertiary)" />
|
|
||||||
<input
|
|
||||||
placeholder="搜索便签..."
|
|
||||||
:value="searchQuery"
|
|
||||||
@input="e => setSearchQuery(e.target.value)"
|
|
||||||
@keydown.enter="handleSearch"
|
|
||||||
style="flex: 1; font-size: 16px; color: var(--text-primary); margin-left: 8px; margin-right: 8px; padding: 0; border: none; background: transparent; outline: none"
|
|
||||||
/>
|
|
||||||
<ion-button
|
|
||||||
v-if="searchQuery.length > 0"
|
|
||||||
fill="clear"
|
|
||||||
@click="() => setSearchQuery('')"
|
|
||||||
style="--padding-start: 0; --padding-end: 0; width: 20px; height: 20px; margin: 0; padding: 0"
|
|
||||||
>
|
|
||||||
<img :src="'/assets/icons/drawable-xxhdpi/search_bar_clear_btn.png'" style="width: 20px; height: 20px; tint-color: var(--text-tertiary)" />
|
|
||||||
</ion-button>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div v-if="filteredAndSortedNotes.length === 0" style="flex: 1; justify-content: center; align-items: center; padding: 16px; background-color: var(--background)">
|
<div v-if="filteredAndSortedNotes.length === 0" style="flex: 1; justify-content: center; align-items: center; padding: 16px">
|
||||||
<ion-text style="font-size: 18px; font-weight: 600; color: var(--text-tertiary); margin-bottom: 8px">
|
<ion-text style="font-size: 18px; font-weight: 600; color: var(--text-tertiary); margin-bottom: 8px"> 未找到便签 </ion-text>
|
||||||
未找到便签
|
|
||||||
</ion-text>
|
|
||||||
<ion-text style="font-size: 14px; color: var(--text-tertiary); text-align: center; line-height: 20px">
|
<ion-text style="font-size: 14px; color: var(--text-tertiary); text-align: center; line-height: 20px">
|
||||||
{{ searchQuery ? '尝试其他搜索词' : '点击 + 按钮创建您的第一条便签' }}
|
{{ searchQuery ? '尝试其他搜索词' : '点击 + 按钮创建您的第一条便签' }}
|
||||||
</ion-text>
|
</ion-text>
|
||||||
</div>
|
</div>
|
||||||
<div v-else style="flex: 1; background-color: var(--background)">
|
<div v-else style="flex: 1">
|
||||||
<ion-text style="font-size: 13px; color: var(--text-tertiary); padding-horizontal: 16px; padding-vertical: 8px; display: block">
|
<ion-text style="font-size: 13px; color: var(--text-tertiary); padding-horizontal: 16px; padding-vertical: 8px; display: block"> {{ filteredAndSortedNotes.length }} 条便签 </ion-text>
|
||||||
{{ filteredAndSortedNotes.length }} 条便签
|
|
||||||
</ion-text>
|
|
||||||
<div style="border-radius: 6px; overflow: hidden; box-shadow: 0 1px 2px var(--shadow); background-color: var(--background-card); margin: 0 16px">
|
<div style="border-radius: 6px; overflow: hidden; box-shadow: 0 1px 2px var(--shadow); background-color: var(--background-card); margin: 0 16px">
|
||||||
<div v-for="note in filteredAndSortedNotes" :key="note.id">
|
<div v-for="note in filteredAndSortedNotes" :key="note.id">
|
||||||
<NoteItem
|
<NoteItem :title="note.title" :content="note.content" :date="formatDate(note.updatedAt)" :isStarred="note.isStarred" :onPress="() => handleNotePress(note.id)" :onDelete="() => handleDeleteNote(note.id)" />
|
||||||
:title="note.title"
|
|
||||||
:content="note.content"
|
|
||||||
:date="formatDate(note.updatedAt)"
|
|
||||||
:isStarred="note.isStarred"
|
|
||||||
:onPress="() => handleNotePress(note.id)"
|
|
||||||
:onDelete="() => handleDeleteNote(note.id)"
|
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- 点击外部区域收起文件夹列表的覆盖层 -->
|
<!-- 点击外部区域收起文件夹列表的覆盖层 -->
|
||||||
<div
|
<div v-if="isFolderExpanded" @click="() => setIsFolderExpanded(false)" style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: transparent; z-index: 99"></div>
|
||||||
v-if="isFolderExpanded"
|
</div>
|
||||||
@click="() => setIsFolderExpanded(false)"
|
|
||||||
style="position: absolute; top: 0; left: 0; right: 0; bottom: 0; background-color: transparent; z-index: 99"
|
|
||||||
></div>
|
|
||||||
|
|
||||||
<ion-alert
|
<ion-alert
|
||||||
:is-open="showAlert"
|
:is-open="showAlert"
|
||||||
@didDismiss="() => setShowAlert(false)"
|
@didDismiss="() => setShowAlert(false)"
|
||||||
@@ -112,165 +63,183 @@
|
|||||||
:buttons="[
|
:buttons="[
|
||||||
{
|
{
|
||||||
text: '取消',
|
text: '取消',
|
||||||
role: 'cancel'
|
role: 'cancel',
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
text: '删除',
|
text: '删除',
|
||||||
handler: confirmDeleteNote
|
handler: confirmDeleteNote,
|
||||||
}
|
},
|
||||||
]"
|
]"></ion-alert>
|
||||||
></ion-alert>
|
</ion-app>
|
||||||
</ion-page>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup>
|
<script setup>
|
||||||
import { ref, computed, onMounted } from 'vue';
|
import { ref, computed, onMounted } from 'vue'
|
||||||
import { useAppStore } from '../stores/useAppStore';
|
import { useAppStore } from '../stores/useAppStore'
|
||||||
import { create, settings } from 'ionicons/icons';
|
import { create, settings } from 'ionicons/icons'
|
||||||
import NoteItem from '../components/NoteItem.vue';
|
import NoteItem from '../components/NoteItem.vue'
|
||||||
import Header from '../components/Header.vue';
|
import Header from '../components/Header.vue'
|
||||||
import FolderItem from '../components/FolderItem.vue';
|
import FolderManage from '../components/FolderManage.vue'
|
||||||
|
import SearchBar from '../components/SearchBar.vue'
|
||||||
|
|
||||||
const store = useAppStore();
|
const store = useAppStore()
|
||||||
|
|
||||||
// 加载初始数据
|
// 加载初始数据
|
||||||
onMounted(() => {
|
onMounted(() => {
|
||||||
store.loadData();
|
store.loadData()
|
||||||
});
|
})
|
||||||
|
|
||||||
const searchQuery = ref('');
|
const searchQuery = ref('')
|
||||||
const sortBy = ref('date'); // 'date', 'title', 'starred'
|
const sortBy = ref('date') // 'date', 'title', 'starred'
|
||||||
const isFolderExpanded = ref(false);
|
const isFolderExpanded = ref(false)
|
||||||
const currentFolder = ref('all'); // 默认文件夹是"全部便签"
|
const currentFolder = ref('all') // 默认文件夹是"全部便签"
|
||||||
const showAlert = ref(false);
|
const showAlert = ref(false)
|
||||||
const noteToDelete = ref(null);
|
const noteToDelete = ref(null)
|
||||||
|
|
||||||
// 计算加星便签数量
|
// 计算加星便签数量
|
||||||
const starredNotesCount = computed(() => {
|
const starredNotesCount = computed(() => {
|
||||||
return store.notes.filter(note => note.isStarred).length;
|
return store.notes.filter(note => note.isStarred).length
|
||||||
});
|
})
|
||||||
|
|
||||||
// 根据当前文件夹过滤便签
|
// 根据当前文件夹过滤便签
|
||||||
const filteredNotes = computed(() => {
|
const filteredNotes = computed(() => {
|
||||||
return store.notes.filter(note => {
|
return store.notes.filter(note => {
|
||||||
switch (currentFolder.value) {
|
switch (currentFolder.value) {
|
||||||
case 'all':
|
case 'all':
|
||||||
return true;
|
return true
|
||||||
case 'starred':
|
case 'starred':
|
||||||
return note.isStarred;
|
return note.isStarred
|
||||||
case 'trash':
|
case 'trash':
|
||||||
// 假设我们有一个isDeleted属性来标识已删除的便签
|
// 假设我们有一个isDeleted属性来标识已删除的便签
|
||||||
return note.isDeleted || false;
|
return note.isDeleted || false
|
||||||
default:
|
default:
|
||||||
return note.folderId === currentFolder.value;
|
return note.folderId === currentFolder.value
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
// Filter and sort notes
|
// Filter and sort notes
|
||||||
const filteredAndSortedNotes = computed(() => {
|
const filteredAndSortedNotes = computed(() => {
|
||||||
return filteredNotes.value
|
return filteredNotes.value
|
||||||
.filter(note =>
|
.filter(note => note.title.toLowerCase().includes(searchQuery.value.toLowerCase()) || note.content.toLowerCase().includes(searchQuery.value.toLowerCase()))
|
||||||
note.title.toLowerCase().includes(searchQuery.value.toLowerCase()) ||
|
|
||||||
note.content.toLowerCase().includes(searchQuery.value.toLowerCase())
|
|
||||||
)
|
|
||||||
.sort((a, b) => {
|
.sort((a, b) => {
|
||||||
if (sortBy.value === 'title') {
|
if (sortBy.value === 'title') {
|
||||||
return a.title.localeCompare(b.title);
|
return a.title.localeCompare(b.title)
|
||||||
} else if (sortBy.value === 'starred') {
|
} else if (sortBy.value === 'starred') {
|
||||||
return (b.isStarred ? 1 : 0) - (a.isStarred ? 1 : 0);
|
return (b.isStarred ? 1 : 0) - (a.isStarred ? 1 : 0)
|
||||||
} else {
|
} else {
|
||||||
return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime();
|
return new Date(b.updatedAt).getTime() - new Date(a.updatedAt).getTime()
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
});
|
})
|
||||||
|
|
||||||
// 计算头部标题
|
// 计算头部标题
|
||||||
const headerTitle = computed(() => {
|
const headerTitle = computed(() => {
|
||||||
switch (currentFolder.value) {
|
switch (currentFolder.value) {
|
||||||
case 'all':
|
case 'all':
|
||||||
return '全部便签';
|
return '全部便签'
|
||||||
case 'starred':
|
case 'starred':
|
||||||
return '加星便签';
|
return '加星便签'
|
||||||
case 'trash':
|
case 'trash':
|
||||||
return '回收站';
|
return '回收站'
|
||||||
default:
|
default:
|
||||||
return '文件夹';
|
return '文件夹'
|
||||||
}
|
}
|
||||||
});
|
})
|
||||||
|
|
||||||
const handleNotePress = (noteId) => {
|
const handleNotePress = noteId => {
|
||||||
// 导航到详情页面的逻辑将在路由中处理
|
// 导航到详情页面的逻辑将在路由中处理
|
||||||
window.location.hash = `#/notes/${noteId}`;
|
window.location.hash = `#/notes/${noteId}`
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleAddNote = () => {
|
const handleAddNote = () => {
|
||||||
// 导航到编辑页面的逻辑将在路由中处理
|
// 导航到编辑页面的逻辑将在路由中处理
|
||||||
window.location.hash = '#/editor';
|
window.location.hash = '#/editor'
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleDeleteNote = (noteId) => {
|
const handleDeleteNote = noteId => {
|
||||||
noteToDelete.value = noteId;
|
noteToDelete.value = noteId
|
||||||
showAlert.value = true;
|
showAlert.value = true
|
||||||
};
|
}
|
||||||
|
|
||||||
const confirmDeleteNote = () => {
|
const confirmDeleteNote = () => {
|
||||||
if (noteToDelete.value) {
|
if (noteToDelete.value) {
|
||||||
store.deleteNote(noteToDelete.value);
|
store.deleteNote(noteToDelete.value)
|
||||||
noteToDelete.value = null;
|
noteToDelete.value = null
|
||||||
}
|
}
|
||||||
showAlert.value = false;
|
showAlert.value = false
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleSort = () => {
|
const handleSort = () => {
|
||||||
// In a full implementation, this would cycle through sort options
|
// In a full implementation, this would cycle through sort options
|
||||||
const sortOptions = ['date', 'title', 'starred'];
|
const sortOptions = ['date', 'title', 'starred']
|
||||||
const currentIndex = sortOptions.indexOf(sortBy.value);
|
const currentIndex = sortOptions.indexOf(sortBy.value)
|
||||||
const nextIndex = (currentIndex + 1) % sortOptions.length;
|
const nextIndex = (currentIndex + 1) % sortOptions.length
|
||||||
sortBy.value = sortOptions[nextIndex];
|
sortBy.value = sortOptions[nextIndex]
|
||||||
console.log('Sort by:', sortOptions[nextIndex]);
|
console.log('Sort by:', sortOptions[nextIndex])
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleFolderPress = () => {
|
const handleFolderPress = () => {
|
||||||
// 导航到文件夹页面的逻辑将在路由中处理
|
// 导航到文件夹页面的逻辑将在路由中处理
|
||||||
window.location.hash = '#/folders';
|
window.location.hash = '#/folders'
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleSettingsPress = () => {
|
const handleSettingsPress = () => {
|
||||||
// 导航到设置页面的逻辑将在路由中处理
|
// 导航到设置页面的逻辑将在路由中处理
|
||||||
window.location.hash = '#/settings';
|
window.location.hash = '#/settings'
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleFolderToggle = () => {
|
const handleFolderToggle = () => {
|
||||||
// 在实际应用中,这里会触发文件夹列表的展开/收起
|
// 在实际应用中,这里会触发文件夹列表的展开/收起
|
||||||
isFolderExpanded.value = !isFolderExpanded.value;
|
isFolderExpanded.value = !isFolderExpanded.value
|
||||||
console.log('Folder expanded:', !isFolderExpanded.value);
|
console.log('Folder expanded:', !isFolderExpanded.value)
|
||||||
};
|
}
|
||||||
|
|
||||||
const handleSearch = () => {
|
const handleSearch = query => {
|
||||||
// In a full implementation, this would filter notes based on searchQuery
|
// 搜索功能已在computed属性filteredAndSortedNotes中实现
|
||||||
console.log('Search for:', searchQuery.value);
|
console.log('Search for:', query)
|
||||||
};
|
}
|
||||||
|
|
||||||
const formatDate = (dateString) => {
|
const handleClearSearch = () => {
|
||||||
return new Date(dateString).toLocaleDateString();
|
// 清除搜索已在v-model中处理
|
||||||
};
|
console.log('Search cleared')
|
||||||
|
}
|
||||||
|
|
||||||
const setCurrentFolder = (folder) => {
|
const handleSearchFocus = () => {
|
||||||
currentFolder.value = folder;
|
console.log('Search bar focused')
|
||||||
};
|
}
|
||||||
|
|
||||||
const setIsFolderExpanded = (expanded) => {
|
const handleSearchBlur = () => {
|
||||||
isFolderExpanded.value = expanded;
|
console.log('Search bar blurred')
|
||||||
};
|
}
|
||||||
|
|
||||||
const setSearchQuery = (query) => {
|
const formatDate = dateString => {
|
||||||
searchQuery.value = query;
|
return new Date(dateString).toLocaleDateString()
|
||||||
};
|
}
|
||||||
|
|
||||||
const setShowAlert = (show) => {
|
const setCurrentFolder = folder => {
|
||||||
showAlert.value = show;
|
currentFolder.value = folder
|
||||||
};
|
}
|
||||||
|
|
||||||
const notes = computed(() => store.notes);
|
const setIsFolderExpanded = expanded => {
|
||||||
|
isFolderExpanded.value = expanded
|
||||||
|
}
|
||||||
|
|
||||||
|
const setSearchQuery = query => {
|
||||||
|
searchQuery.value = query
|
||||||
|
}
|
||||||
|
|
||||||
|
const setShowAlert = show => {
|
||||||
|
showAlert.value = show
|
||||||
|
}
|
||||||
|
|
||||||
|
const notes = computed(() => store.notes)
|
||||||
</script>
|
</script>
|
||||||
|
<style lang="less" scoped>
|
||||||
|
.container {
|
||||||
|
width: 100vw;
|
||||||
|
height: 100vh;
|
||||||
|
background: url(assets/icons/drawable-xxhdpi/note_background.png);
|
||||||
|
background-size: cover;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
|||||||
Reference in New Issue
Block a user