You've already forked SmartisanNote.Remake
调整了编辑器的样式;
调整了头部的按钮;
This commit is contained in:
@@ -12,7 +12,16 @@
|
|||||||
</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" />
|
||||||
|
|
||||||
|
<div v-else-if="actionIcon === 'save'" class="code-fun-flex-row code-fun-items-center right-group">
|
||||||
|
<!-- 插入图片 -->
|
||||||
|
<img class="image_4" src="/assets/icons/drawable-xxhdpi/btn_pic.png" @click="handleAction" />
|
||||||
|
<!-- 保存便签 -->
|
||||||
|
<img class="image_4" src="/assets/icons/drawable-xxhdpi/btn_save_notes.png" @click="handleAction" />
|
||||||
|
</div>
|
||||||
|
<!-- 占位符 -->
|
||||||
<div v-else class="image_4-placeholder"></div>
|
<div v-else class="image_4-placeholder"></div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -24,7 +33,7 @@ import { ref, computed } from 'vue'
|
|||||||
const props = defineProps({
|
const props = defineProps({
|
||||||
title: {
|
title: {
|
||||||
type: String,
|
type: String,
|
||||||
required: true,
|
default: '',
|
||||||
},
|
},
|
||||||
onBack: {
|
onBack: {
|
||||||
type: Function,
|
type: Function,
|
||||||
@@ -131,6 +140,8 @@ const handleTitlePress = () => {
|
|||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
align-items: center;
|
align-items: center;
|
||||||
|
margin-bottom: -2.8rem;
|
||||||
|
position: relative;
|
||||||
.inner {
|
.inner {
|
||||||
display: flex;
|
display: flex;
|
||||||
justify-content: space-between;
|
justify-content: space-between;
|
||||||
@@ -139,14 +150,17 @@ const handleTitlePress = () => {
|
|||||||
}
|
}
|
||||||
.left-icon,
|
.left-icon,
|
||||||
.image_4 {
|
.image_4 {
|
||||||
width: 1.7rem;
|
width: 1.8rem;
|
||||||
height: 1.7rem;
|
height: 1.8rem;
|
||||||
cursor: pointer;
|
cursor: pointer;
|
||||||
}
|
}
|
||||||
|
.right-group {
|
||||||
|
gap: .6rem;
|
||||||
|
}
|
||||||
|
|
||||||
.image_4-placeholder {
|
.image_4-placeholder {
|
||||||
width: 1.7rem;
|
width: 1.8rem;
|
||||||
height: 1.7rem;
|
height: 1.8rem;
|
||||||
}
|
}
|
||||||
|
|
||||||
.title-container {
|
.title-container {
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ const insertQuote = () => {
|
|||||||
icon.alt = '引用'
|
icon.alt = '引用'
|
||||||
|
|
||||||
// 创建内容容器
|
// 创建内容容器
|
||||||
const contentSpan = document.createElement('blockquote')
|
const contentSpan = document.createElement('div')
|
||||||
contentSpan.className = 'quote-content'
|
contentSpan.className = 'quote-content'
|
||||||
contentSpan.textContent = '引用内容'
|
contentSpan.textContent = '引用内容'
|
||||||
|
|
||||||
@@ -222,7 +222,7 @@ const insertTodoList = () => {
|
|||||||
icon.alt = '待办事项'
|
icon.alt = '待办事项'
|
||||||
|
|
||||||
// 创建内容容器
|
// 创建内容容器
|
||||||
const contentSpan = document.createElement('span')
|
const contentSpan = document.createElement('div')
|
||||||
contentSpan.contentEditable = true
|
contentSpan.contentEditable = true
|
||||||
contentSpan.className = 'todo-content'
|
contentSpan.className = 'todo-content'
|
||||||
contentSpan.textContent = '待办事项'
|
contentSpan.textContent = '待办事项'
|
||||||
@@ -292,7 +292,7 @@ const insertTodoList = () => {
|
|||||||
newIcon.alt = '待办事项'
|
newIcon.alt = '待办事项'
|
||||||
|
|
||||||
// 创建内容容器
|
// 创建内容容器
|
||||||
const newContentSpan = document.createElement('span')
|
const newContentSpan = document.createElement('div')
|
||||||
newContentSpan.contentEditable = true
|
newContentSpan.contentEditable = true
|
||||||
newContentSpan.className = 'todo-content'
|
newContentSpan.className = 'todo-content'
|
||||||
newContentSpan.textContent = ''
|
newContentSpan.textContent = ''
|
||||||
@@ -360,7 +360,7 @@ const insertTodoList = () => {
|
|||||||
nextIcon.alt = '待办事项'
|
nextIcon.alt = '待办事项'
|
||||||
|
|
||||||
// 创建内容容器
|
// 创建内容容器
|
||||||
const nextContentSpan = document.createElement('span')
|
const nextContentSpan = document.createElement('div')
|
||||||
nextContentSpan.contentEditable = true
|
nextContentSpan.contentEditable = true
|
||||||
nextContentSpan.className = 'todo-content'
|
nextContentSpan.className = 'todo-content'
|
||||||
nextContentSpan.textContent = ''
|
nextContentSpan.textContent = ''
|
||||||
@@ -572,7 +572,7 @@ defineExpose({
|
|||||||
|
|
||||||
.editor-content {
|
.editor-content {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
padding: 20px 16px;
|
padding: 20px 10px;
|
||||||
outline: none;
|
outline: none;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
font-size: 16px;
|
font-size: 16px;
|
||||||
@@ -581,6 +581,22 @@ defineExpose({
|
|||||||
min-height: 200px;
|
min-height: 200px;
|
||||||
background-color: var(--background-card);
|
background-color: var(--background-card);
|
||||||
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, Oxygen, Ubuntu, Cantarell, 'Open Sans', 'Helvetica Neue', sans-serif;
|
||||||
|
position: relative;
|
||||||
|
/* 基准线样式 */
|
||||||
|
background-image: linear-gradient(to bottom, var(--border) 1px, transparent 1px);
|
||||||
|
background-size: 100% 25.6px; /* 16px * 1.6 = 25.6px */
|
||||||
|
background-repeat: repeat-y;
|
||||||
|
background-position: 0 20px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.editor-content::before {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 统一处理所有直接子元素的间距 */
|
||||||
|
.editor-content > * {
|
||||||
|
margin: 0;
|
||||||
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-content:focus,
|
.editor-content:focus,
|
||||||
@@ -588,69 +604,72 @@ defineExpose({
|
|||||||
outline: none;
|
outline: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 自定义内容样式 */
|
/* 优化段落样式,确保与基准线对齐 */
|
||||||
|
:deep(.editor-content p) {
|
||||||
|
margin: 0 0 12px 0;
|
||||||
|
line-height: 1.6;
|
||||||
|
letter-spacing: 0.3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 自定义内容样式 - 统一行高和间距 */
|
||||||
:deep(.editor-content h2) {
|
:deep(.editor-content h2) {
|
||||||
font-size: 20px;
|
font-size: 20px;
|
||||||
font-weight: 600;
|
font-weight: 600;
|
||||||
margin: 8px 0 8px 0;
|
margin: 0 0 12px 0;
|
||||||
color: var(--note-title);
|
color: var(--note-title);
|
||||||
line-height: 1.4;
|
line-height: 1.6;
|
||||||
letter-spacing: 0.5px;
|
letter-spacing: 0.3px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
position: relative;
|
position: relative;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.editor-content blockquote) {
|
:deep(.editor-content blockquote) {
|
||||||
border-left: 3px solid var(--primary);
|
border-left: 3px solid var(--primary);
|
||||||
padding-left: 16px;
|
padding: 0 16px 0 16px;
|
||||||
margin: 16px 0;
|
margin: 0 0 12px 0;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
background-color: var(--background-secondary);
|
background-color: var(--background-secondary);
|
||||||
padding: 8px 16px 8px 16px;
|
|
||||||
border-radius: 0 4px 4px 0;
|
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.quote-container) {
|
:deep(.quote-container) {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 16px 0;
|
margin: 0 0 12px 0;
|
||||||
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.quote-icon) {
|
:deep(.quote-icon) {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 10px;
|
top: 0;
|
||||||
width: 16px;
|
width: 16px;
|
||||||
height: 16px;
|
height: 16px;
|
||||||
|
margin-top: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.quote-content) {
|
:deep(.quote-content) {
|
||||||
border-left: 3px solid var(--primary);
|
border-left: 3px solid var(--primary);
|
||||||
padding-left: 32px;
|
padding: 0 16px 0 32px;
|
||||||
margin-left: 16px;
|
margin-left: 16px;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
background-color: var(--background-secondary);
|
background-color: var(--background-secondary);
|
||||||
padding: 8px 16px 8px 16px;
|
|
||||||
border-radius: 0 4px 4px 0;
|
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.editor-content ul),
|
:deep(.editor-content ul),
|
||||||
:deep(.editor-content ol) {
|
:deep(.editor-content ol) {
|
||||||
margin: 16px 0;
|
margin: 0 0 12px 0;
|
||||||
padding-left: 32px;
|
padding-left: 32px;
|
||||||
position: relative;
|
position: relative;
|
||||||
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.editor-content li) {
|
:deep(.editor-content li) {
|
||||||
margin: 6px 0;
|
margin: 0;
|
||||||
line-height: 1.5;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.editor-content p) {
|
|
||||||
margin: 0 0 12px 0;
|
|
||||||
line-height: 1.6;
|
line-height: 1.6;
|
||||||
letter-spacing: 0.3px;
|
padding: 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.editor-content strong) {
|
:deep(.editor-content strong) {
|
||||||
@@ -672,64 +691,61 @@ defineExpose({
|
|||||||
border: none;
|
border: none;
|
||||||
height: 1px;
|
height: 1px;
|
||||||
background-color: var(--border);
|
background-color: var(--border);
|
||||||
margin: 20px 0;
|
margin: 12px 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.editor-content div[style*='text-align: center'] {
|
.editor-content div[style*='text-align: center'] {
|
||||||
text-align: center;
|
text-align: center;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 待办事项样式 */
|
|
||||||
:deep(.todo-container) {
|
|
||||||
display: flex;
|
|
||||||
align-items: flex-start;
|
|
||||||
margin: 0.1rem 0;
|
|
||||||
padding: 0.02rem 0;
|
|
||||||
position: relative;
|
|
||||||
padding-left: 1.2rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.todo-icon) {
|
|
||||||
position: absolute;
|
|
||||||
left: 0;
|
|
||||||
top: 0;
|
|
||||||
width: 2rem;
|
|
||||||
height: 2rem;
|
|
||||||
cursor: pointer;
|
|
||||||
}
|
|
||||||
|
|
||||||
:deep(.todo-content) {
|
|
||||||
flex: 1;
|
|
||||||
outline: none;
|
|
||||||
padding: 0.125rem 0.25rem;
|
|
||||||
min-height: 1.25rem;
|
|
||||||
border-radius: 0.125rem;
|
|
||||||
color: var(--note-content);
|
|
||||||
margin-left: 0.5rem;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* 引用格式样式 */
|
/* 引用格式样式 */
|
||||||
:deep(.quote-container) {
|
:deep(.quote-container) {
|
||||||
position: relative;
|
position: relative;
|
||||||
margin: 1rem 0;
|
margin: 0 0 12px 0;
|
||||||
|
line-height: 1.6;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.quote-icon) {
|
:deep(.quote-icon) {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
left: 0;
|
left: 0;
|
||||||
top: 0.625rem;
|
top: 0;
|
||||||
width: 1rem;
|
width: 16px;
|
||||||
height: 1rem;
|
height: 16px;
|
||||||
|
margin-top: 3px;
|
||||||
}
|
}
|
||||||
|
|
||||||
:deep(.quote-content) {
|
:deep(.quote-content) {
|
||||||
border-left: 0.1875rem solid var(--primary);
|
border-left: 3px solid var(--primary);
|
||||||
padding-left: 2rem;
|
padding: 0 16px 0 32px;
|
||||||
margin-left: 1.5rem;
|
margin-left: 16px;
|
||||||
color: var(--text-secondary);
|
color: var(--text-secondary);
|
||||||
background-color: var(--background-secondary);
|
background-color: var(--background-secondary);
|
||||||
padding: 0.5rem 1rem;
|
|
||||||
border-radius: 0 0.25rem 0.25rem 0;
|
|
||||||
font-style: italic;
|
font-style: italic;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* 待办事项样式 */
|
||||||
|
:deep(.todo-container) {
|
||||||
|
display: flex;
|
||||||
|
align-items: center;
|
||||||
|
margin: 0;
|
||||||
|
line-height: 1.6;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.todo-icon) {
|
||||||
|
width: 25px;
|
||||||
|
height: 25px;
|
||||||
|
margin-right: 2px;
|
||||||
|
margin-top: 0;
|
||||||
|
cursor: pointer;
|
||||||
|
flex-shrink: 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
:deep(.todo-content) {
|
||||||
|
flex: 1;
|
||||||
|
outline: none;
|
||||||
|
line-height: 1.6;
|
||||||
|
padding: 0;
|
||||||
|
margin: 0;
|
||||||
}
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<ion-page>
|
<ion-page>
|
||||||
<div class="container">
|
<div class="container">
|
||||||
<Header :title="isEditing ? '编辑便签' : '新建便签'" :onBack="handleCancel" :onAction="handleSave" actionText="保存" />
|
<Header :onBack="handleCancel" :onAction="handleSave" actionIcon="save" />
|
||||||
|
|
||||||
<!-- 富文本编辑器 -->
|
<!-- 富文本编辑器 -->
|
||||||
<div class="editor-container">
|
<div class="editor-container">
|
||||||
@@ -64,25 +64,23 @@ const showAlert = ref(false)
|
|||||||
|
|
||||||
// 计算属性
|
// 计算属性
|
||||||
const formattedTime = computed(() => {
|
const formattedTime = computed(() => {
|
||||||
if (!isEditing) return '新建便签'
|
|
||||||
|
|
||||||
const date = new Date(existingNote.updatedAt)
|
|
||||||
const now = new Date()
|
const now = new Date()
|
||||||
|
const date = existingNote?.updatedAt ? new Date(existingNote.updatedAt) : now
|
||||||
|
|
||||||
// 如果是今天
|
// 如果是今天
|
||||||
if (date.toDateString() === now.toDateString()) {
|
if (date.toDateString() === now.toDateString()) {
|
||||||
return `编辑于 今天 ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`
|
return `今天 ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 如果是昨天
|
// 如果是昨天
|
||||||
const yesterday = new Date(now)
|
const yesterday = new Date(now)
|
||||||
yesterday.setDate(yesterday.getDate() - 1)
|
yesterday.setDate(yesterday.getDate() - 1)
|
||||||
if (date.toDateString() === yesterday.toDateString()) {
|
if (date.toDateString() === yesterday.toDateString()) {
|
||||||
return `编辑于 昨天 ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`
|
return `昨天 ${date.getHours().toString().padStart(2, '0')}:${date.getMinutes().toString().padStart(2, '0')}`
|
||||||
}
|
}
|
||||||
|
|
||||||
// 其他情况显示月日
|
// 其他情况显示月日
|
||||||
return `编辑于 ${date.getMonth() + 1}月${date.getDate()}日`
|
return `${date.getMonth() + 1}月${date.getDate()}日`
|
||||||
})
|
})
|
||||||
|
|
||||||
const wordCount = computed(() => {
|
const wordCount = computed(() => {
|
||||||
@@ -140,31 +138,6 @@ const setShowAlert = value => {
|
|||||||
background-color: var(--background);
|
background-color: var(--background);
|
||||||
}
|
}
|
||||||
|
|
||||||
.toolbar {
|
|
||||||
display: flex;
|
|
||||||
padding: 8px 16px;
|
|
||||||
border-bottom: 1px solid var(--border);
|
|
||||||
background-color: var(--background-card);
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar-btn {
|
|
||||||
padding: 8px;
|
|
||||||
margin-right: 8px;
|
|
||||||
border: none;
|
|
||||||
background: transparent;
|
|
||||||
cursor: pointer;
|
|
||||||
border-radius: 4px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar-btn:hover {
|
|
||||||
background-color: var(--background-hover);
|
|
||||||
}
|
|
||||||
|
|
||||||
.toolbar-icon {
|
|
||||||
width: 24px;
|
|
||||||
height: 24px;
|
|
||||||
}
|
|
||||||
|
|
||||||
.editor-container {
|
.editor-container {
|
||||||
flex: 1;
|
flex: 1;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
|
|||||||
@@ -35,24 +35,23 @@
|
|||||||
<!-- 点击外部区域收起文件夹列表的覆盖层 -->
|
<!-- 点击外部区域收起文件夹列表的覆盖层 -->
|
||||||
<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>
|
<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>
|
||||||
|
|
||||||
<div style="padding: 0.8rem 0.5rem; margin-top: -2.8rem">
|
<div style="padding: 0.8rem 0.5rem">
|
||||||
<SearchBar v-model="searchQuery" @search="handleSearch" @clear="handleClearSearch" @focus="handleSearchFocus" @blur="handleSearchBlur" />
|
<SearchBar v-model="searchQuery" @search="handleSearch" @clear="handleClearSearch" @focus="handleSearchFocus" @blur="handleSearchBlur" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div style="flex: 1">
|
<div style="flex: 1">
|
||||||
<div v-for="note in filteredAndSortedNotes" :key="note.id" style="margin: 0.4rem 0">
|
<div v-for="note in filteredAndSortedNotes" :key="note.id" style="margin: 0.4rem 0">
|
||||||
<NoteItem
|
<NoteItem
|
||||||
:title="note.title"
|
:title="note.title"
|
||||||
:content="note.content"
|
:content="note.content"
|
||||||
:date="formatDate(note.updatedAt)"
|
:date="formatDate(note.updatedAt)"
|
||||||
:isStarred="note.isStarred"
|
:isStarred="note.isStarred"
|
||||||
:isTop="note.isTop || false"
|
:isTop="note.isTop || false"
|
||||||
:hasImage="note.hasImage || false"
|
:hasImage="note.hasImage || false"
|
||||||
:onPress="() => handleNotePress(note.id)"
|
:onPress="() => handleNotePress(note.id)"
|
||||||
:onStarToggle="() => handleStarToggle(note.id)"
|
:onStarToggle="() => handleStarToggle(note.id)"
|
||||||
:onTopToggle="() => handleTopToggle(note.id)"
|
:onTopToggle="() => handleTopToggle(note.id)"
|
||||||
:onDelete="() => handleDeleteNote(note.id)"
|
:onDelete="() => handleDeleteNote(note.id)" />
|
||||||
/>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user