新增 离线web应用发布流程;

移除了便签详情页;
优化了若干逻辑;
新增 移动端、IOS兼容处理;
This commit is contained in:
2025-10-12 06:05:27 +08:00
parent 1ae28a8040
commit d1365aaaa5
11 changed files with 312 additions and 198 deletions

View File

@@ -1,120 +0,0 @@
<template>
<ion-page>
<Header
:title="note ? note.title : '未找到便签'"
:onBack="() => window.history.back()"
:onAction="note ? handleEdit : null"
actionIcon="settings"
/>
<ion-content v-if="!note">
<div style="display: flex; justify-content: center; align-items: center; height: 100%; background-color: var(--background)">
<ion-text>未找到该便签</ion-text>
</div>
</ion-content>
<ion-content v-else>
<div style="padding: 16px; background-color: var(--background-card)">
<div style="display: flex; justify-content: space-between; align-items: center; margin-bottom: 16px; padding-bottom: 16px; border-bottom: 1px solid var(--border)">
<ion-text style="color: var(--note-date); font-size: 14px">
最后更新: {{ formatDate(note.updatedAt) }}
</ion-text>
<ion-button fill="clear" @click="handleStar">
<ion-icon
:icon="note.isStarred ? star : starOutline"
:style="{ fontSize: '24px', color: note.isStarred ? 'var(--note-star)' : 'var(--text-tertiary)' }"
></ion-icon>
</ion-button>
</div>
<div style="white-space: pre-wrap; line-height: 1.6; font-size: 16px; color: var(--note-content)">
{{ note.content }}
</div>
</div>
<div style="position: absolute; bottom: 0; left: 0; right: 0; display: flex; justify-content: space-around; padding: 10px; background-color: var(--background); border-top: 1px solid var(--border)">
<div style="display: flex; flex-direction: column; align-items: center">
<ion-button fill="clear" @click="handleShare">
<ion-icon :icon="share" style="font-size: 24px; color: var(--text-primary)"></ion-icon>
</ion-button>
<ion-text style="font-size: 12px; color: var(--text-primary)">分享</ion-text>
</div>
<div style="display: flex; flex-direction: column; align-items: center">
<ion-button fill="clear" @click="handleMoveToFolder">
<ion-icon :icon="folder" style="font-size: 24px; color: var(--text-primary)"></ion-icon>
</ion-button>
<ion-text style="font-size: 12px; color: var(--text-primary)">文件夹</ion-text>
</div>
<div style="display: flex; flex-direction: column; align-items: center">
<ion-button fill="clear" @click="handleReminder">
<ion-icon :icon="alarm" style="font-size: 24px; color: var(--text-primary)"></ion-icon>
</ion-button>
<ion-text style="font-size: 12px; color: var(--text-primary)">提醒</ion-text>
</div>
<div style="display: flex; flex-direction: column; align-items: center">
<ion-button fill="clear" @click="handleDelete">
<ion-icon :icon="trash" style="font-size: 24px; color: var(--text-primary)"></ion-icon>
</ion-button>
<ion-text style="font-size: 12px; color: var(--text-primary)">删除</ion-text>
</div>
</div>
</ion-content>
</ion-page>
</template>
<script setup>
import { computed, onMounted } from 'vue';
import { useAppStore } from '../stores/useAppStore';
import { star, starOutline, share, folder, alarm, trash } from 'ionicons/icons';
import Header from '../components/Header.vue';
const props = defineProps({
noteId: {
type: String,
required: true
}
});
const store = useAppStore();
// 加载初始数据
onMounted(() => {
store.loadData();
});
// Find the note by ID
const note = computed(() => store.notes.find(n => n.id === props.noteId));
const handleEdit = () => {
// 导航到编辑页面的逻辑将在路由中处理
window.location.hash = `#/editor/${props.noteId}`;
};
const handleShare = () => {
// In a full implementation, this would share the note
console.log('Share note');
};
const handleMoveToFolder = () => {
// In a full implementation, this would move the note to a folder
console.log('Move to folder');
};
const handleDelete = () => {
// In a full implementation, this would delete the note
console.log('Delete note');
};
const handleStar = async () => {
// Toggle star status
if (note.value) {
await store.updateNote(props.noteId, { isStarred: !note.value.isStarred });
}
};
const handleReminder = () => {
// In a full implementation, this would set a reminder
console.log('Set reminder');
};
const formatDate = (dateString) => {
return new Date(dateString).toLocaleDateString();
};
</script>

View File

@@ -1,10 +1,10 @@
<template>
<ion-page>
<div class="container">
<Header :onBack="handleCancel" :onAction="handleSave" actionIcon="save" />
<Header :onBack="handleCancel" :onAction="handleAction" actionIcon="save" />
<!-- 顶部信息栏 -->
<div class="header-info">
<div class="header-info" v-if="isEditing">
<span class="edit-time">{{ formattedTime }}</span>
<span>|</span>
<span class="word-count">{{ wordCount }}</span>
@@ -126,6 +126,38 @@ const handleCancel = () => {
}
}
// 处理创建(用于新建便签)
const handleCreate = async () => {
try {
// Create new note
await store.addNote({
content: content.value,
isStarred: false,
})
// Navigate back to the previous screen
window.location.hash = '#/notes'
} catch (error) {
// In a full implementation, show an alert or toast
console.log('Create error: Failed to create note. Please try again.')
}
}
// 处理Header组件的操作按钮点击事件
const handleAction = actionType => {
if (actionType === 'save') {
handleSave()
} else if (actionType === 'create') {
handleCreate()
} else if (actionType === 'insertImage') {
// 插入图片功能
if (editorRef.value) {
// 通过editorRef调用RichTextEditor组件的方法来插入图片
editorRef.value.insertImage()
}
}
}
const setShowAlert = value => {
showAlert.value = value
}

View File

@@ -1,7 +1,7 @@
<template>
<ion-app>
<div class="container">
<Header :title="headerTitle" :onAction="handleAddNote" actionIcon="create" leftType="settings" :onLeftAction="handleSettingsPress" :onFolderToggle="handleFolderToggle" :isFolderExpanded="isFolderExpanded" :onTitlePress="handleFolderToggle" />
<Header :title="headerTitle" :onAction="handleHeaderAction" actionIcon="create" leftType="settings" :onLeftAction="handleSettingsPress" :onFolderToggle="handleFolderToggle" :isFolderExpanded="isFolderExpanded" :onTitlePress="handleFolderToggle" />
<!-- 悬浮文件夹列表 - 使用绝对定位实现 -->
<div
@@ -163,8 +163,8 @@ const headerTitle = computed(() => {
})
const handleNotePress = noteId => {
// 导航到详情页面的逻辑将在路由中处理
window.location.hash = `#/notes/${noteId}`
// 导航到编辑页面的逻辑将在路由中处理
window.location.hash = `#/editor/${noteId}`
}
const handleAddNote = () => {
@@ -172,6 +172,13 @@ const handleAddNote = () => {
window.location.hash = '#/editor'
}
// 处理Header组件的操作按钮点击事件
const handleHeaderAction = (actionType) => {
if (actionType === 'create') {
handleAddNote()
}
}
const handleDeleteNote = noteId => {
noteToDelete.value = noteId
showAlert.value = true