234 lines
13 KiB
HTML
234 lines
13 KiB
HTML
<!DOCTYPE html>
|
|
<html lang="zh-CN">
|
|
|
|
<head>
|
|
<meta charset="UTF-8">
|
|
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
|
<title>Outlook 邮件管理</title>
|
|
<!-- DOMPurify for XSS protection -->
|
|
<script src="https://cdn.jsdelivr.net/npm/dompurify@3.0.8/dist/purify.min.js"></script>
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/main.css') }}">
|
|
<!-- 可调整布局系统:需在 main.css 之后引入以覆盖旧布局样式 -->
|
|
<link rel="stylesheet" href="{{ url_for('static', filename='css/layout.css') }}">
|
|
</head>
|
|
|
|
<body>
|
|
<!-- 顶部导航栏 -->
|
|
<nav class="navbar">
|
|
<div class="navbar-brand">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
<path d="M4 4h16c1.1 0 2 .9 2 2v12c0 1.1-.9 2-2 2H4c-1.1 0-2-.9-2-2V6c0-1.1.9-2 2-2z"></path>
|
|
<polyline points="22,6 12,13 2,6"></polyline>
|
|
</svg>
|
|
Outlook 邮件
|
|
<span class="app-version">v{{ APP_VERSION }}</span>
|
|
<a href="https://github.com/assast/outlookEmail" target="_blank" class="github-star-btn"
|
|
style="margin-left: 16px;">
|
|
<svg viewBox="0 0 16 16" fill="currentColor">
|
|
<path
|
|
d="M8 .25a.75.75 0 01.673.418l1.882 3.815 4.21.612a.75.75 0 01.416 1.279l-3.046 2.97.719 4.192a.75.75 0 01-1.088.791L8 12.347l-3.766 1.98a.75.75 0 01-1.088-.79l.72-4.194L.818 6.374a.75.75 0 01.416-1.28l4.21-.611L7.327.668A.75.75 0 018 .25z" />
|
|
</svg>
|
|
Star on GitHub
|
|
</a>
|
|
</div>
|
|
<div class="navbar-center">
|
|
<div class="current-account" id="currentAccount" onclick="copyCurrentEmail()" title="点击复制邮箱地址">
|
|
当前邮箱:<strong id="currentAccountEmail"></strong>
|
|
</div>
|
|
</div>
|
|
<div class="navbar-actions">
|
|
<button class="navbar-btn" onclick="showRefreshModal()">全量刷新Token</button>
|
|
<button class="navbar-btn" onclick="showExportModal()">导出邮箱</button>
|
|
<button class="navbar-btn" onclick="showSettingsModal()">⚙️ 设置</button>
|
|
<button class="navbar-btn reset-layout-btn" onclick="showResetLayoutModal()"
|
|
aria-label="恢复默认布局" title="恢复默认布局">
|
|
<svg viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2"
|
|
stroke-linecap="round" stroke-linejoin="round" aria-hidden="true">
|
|
<polyline points="1 4 1 10 7 10"></polyline>
|
|
<path d="M3.51 15a9 9 0 102.13-9.36L1 10"></path>
|
|
</svg>
|
|
</button>
|
|
<button class="navbar-btn" onclick="logout()" style="color: #dc3545;">退出登录</button>
|
|
</div>
|
|
</nav>
|
|
|
|
<!-- 主容器 -->
|
|
<div class="main-container">
|
|
<!-- 分组面板 -->
|
|
<div class="group-panel resizable-panel" id="groupPanel" data-panel="groups">
|
|
<div class="panel-header">
|
|
<span class="panel-title">分组</span>
|
|
<div style="display: flex; align-items: center; gap: 4px;">
|
|
<button class="panel-action-btn" onclick="showAddGroupModal()" title="添加分组">+</button>
|
|
<button class="panel-action-btn collapse-btn" data-panel="groups" aria-label="折叠分组面板"
|
|
aria-expanded="true" title="折叠分组面板">
|
|
←
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="group-list" id="groupList">
|
|
<!-- 分组列表将通过 JS 动态加载 -->
|
|
</div>
|
|
<div class="resizer" role="separator" aria-orientation="vertical" aria-label="调整分组面板宽度"
|
|
aria-valuenow="200" aria-valuemin="150" aria-valuemax="400" tabindex="0" data-resizer="groups">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 邮箱账号面板 -->
|
|
<div class="account-panel resizable-panel" id="accountPanel" data-panel="accounts">
|
|
<div class="account-panel-header">
|
|
<div class="account-panel-title" id="accountPanelTitle">
|
|
<span class="group-color" id="currentGroupColor" style="background-color: #666"></span>
|
|
<span id="currentGroupName">选择分组</span>
|
|
</div>
|
|
<div style="margin-left: auto;">
|
|
<button class="panel-action-btn" onclick="showTagManagementModal()" title="管理标签">
|
|
🏷️
|
|
</button>
|
|
<button class="panel-action-btn" onclick="showAddAccountModal()" title="导入账号">
|
|
<svg width="16" height="16" viewBox="0 0 16 16" fill="currentColor">
|
|
<path fill-rule="evenodd"
|
|
d="M8 2a.75.75 0 01.75.75v4.5h4.5a.75.75 0 010 1.5h-4.5v4.5a.75.75 0 01-1.5 0v-4.5h-4.5a.75.75 0 010-1.5h4.5v-4.5A.75.75 0 018 2z" />
|
|
</svg>
|
|
</button>
|
|
<button class="panel-action-btn collapse-btn" data-panel="accounts" aria-label="折叠账号面板"
|
|
aria-expanded="true" title="折叠账号面板">
|
|
←
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div class="search-container">
|
|
<input type="text" id="globalSearch" class="search-input" placeholder="搜索邮箱地址..." autocomplete="off">
|
|
</div>
|
|
<div class="sort-control"
|
|
style="padding: 8px 16px; border-bottom: 1px solid #e5e5e5; display: flex; align-items: center; gap: 8px; background-color: #fafafa;">
|
|
<label style="font-size: 12px; color: #666; font-weight: 500;">排序:</label>
|
|
<div style="display: flex; gap: 4px;">
|
|
<button class="sort-btn active" data-sort="refresh_time" onclick="sortAccounts('refresh_time')"
|
|
style="padding: 4px 10px; font-size: 12px; background-color: #1a1a1a; border: 1px solid #1a1a1a; border-radius: 4px; color: #ffffff; cursor: pointer; transition: all 0.15s;">
|
|
🕐 刷新时间
|
|
</button>
|
|
<button class="sort-btn" data-sort="email" onclick="sortAccounts('email')"
|
|
style="padding: 4px 10px; font-size: 12px; background-color: #ffffff; border: 1px solid #e5e5e5; border-radius: 4px; color: #666; cursor: pointer; transition: all 0.15s;">
|
|
📧 邮箱名
|
|
</button>
|
|
</div>
|
|
<!-- 全选复选框 -->
|
|
<div style="display: flex; align-items: center; gap: 4px; margin-left: auto;">
|
|
<input type="checkbox" id="selectAllCheckbox" onclick="toggleSelectAll()"
|
|
style="width: 14px; height: 14px; cursor: pointer;">
|
|
<label for="selectAllCheckbox" style="font-size: 12px; color: #666; cursor: pointer;">全选</label>
|
|
</div>
|
|
</div>
|
|
<!-- Tag Filter Row -->
|
|
<div id="tagFilterContainer"
|
|
style="padding: 8px 16px; border-bottom: 1px solid #e5e5e5; display: flex; flex-wrap: wrap; gap: 8px; background-color: #fafafa; display: none;">
|
|
<!-- Tags checkboxes will be rendered here -->
|
|
</div>
|
|
<div class="account-list" id="accountList">
|
|
<div class="empty-state">
|
|
<div class="empty-state-icon">📁</div>
|
|
<div class="empty-state-text">请从左侧选择一个分组</div>
|
|
</div>
|
|
</div>
|
|
<!-- 批量操作栏 -->
|
|
<div id="batchActionBar"
|
|
style="display: none; padding: 8px 16px; border-top: 1px solid #e5e5e5; background: #f8f9fa; gap: 8px; align-items: center;">
|
|
<span id="selectedCount" style="font-size: 12px; color: #666;">已选 0 项</span>
|
|
<div style="flex: 1;"></div>
|
|
<button class="btn btn-sm btn-secondary" onclick="showBatchTagModal('add')">打标签</button>
|
|
<button class="btn btn-sm btn-secondary" onclick="showBatchTagModal('remove')">去标签</button>
|
|
<button class="btn btn-sm btn-secondary" onclick="showBatchMoveGroupModal()">移动分组</button>
|
|
<button class="btn btn-sm btn-danger" onclick="showBatchDeleteConfirm()" style="background-color: #dc3545; border-color: #dc3545; color: white;">删除</button>
|
|
</div>
|
|
<div class="account-panel-footer">
|
|
<button class="add-account-btn" onclick="showAddAccountModal()">+ 导入邮箱</button>
|
|
</div>
|
|
<div class="resizer" role="separator" aria-orientation="vertical" aria-label="调整账号面板宽度"
|
|
aria-valuenow="260" aria-valuemin="180" aria-valuemax="500" tabindex="0" data-resizer="accounts">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 邮件列表面板 -->
|
|
<div class="email-list-panel resizable-panel" id="emailListPanel" data-panel="emails">
|
|
<div class="email-list-header">
|
|
<div style="display: flex; align-items: center; justify-content: space-between; margin-bottom: 12px;">
|
|
<div class="folder-tabs" id="folderTabs" style="display: none;">
|
|
<button class="folder-tab active" data-folder="inbox" onclick="switchFolder('inbox')">
|
|
📨 收件箱
|
|
</button>
|
|
<button class="folder-tab" data-folder="junkemail" onclick="switchFolder('junkemail')">
|
|
⚠️ 垃圾邮件
|
|
</button>
|
|
</div>
|
|
<div style="display: flex; align-items: center; gap: 8px;">
|
|
<button class="refresh-btn" onclick="refreshEmails()">获取邮件</button>
|
|
<button class="panel-action-btn collapse-btn" data-panel="emails" aria-label="折叠邮件列表面板"
|
|
aria-expanded="true" title="折叠邮件列表面板">
|
|
←
|
|
</button>
|
|
</div>
|
|
</div>
|
|
<div style="display: flex; align-items: center; gap: 8px;">
|
|
<h2 style="margin: 0; font-size: 16px; font-weight: 600;">
|
|
邮件
|
|
<span class="email-count" id="emailCount"></span>
|
|
</h2>
|
|
<span class="method-tag" id="methodTag" style="display:none;"></span>
|
|
</div>
|
|
</div>
|
|
<div class="email-list" id="emailList">
|
|
<div class="empty-state">
|
|
<div class="empty-state-icon">📬</div>
|
|
<div class="empty-state-text">请从左侧选择一个邮箱账号</div>
|
|
</div>
|
|
</div>
|
|
<!-- Email Batch Action Bar -->
|
|
<div id="emailBatchActionBar"
|
|
style="display: none; padding: 8px 16px; border-top: 1px solid #e5e5e5; background: #f8f9fa; gap: 8px; align-items: center;">
|
|
<span id="emailSelectedCount" style="font-size: 12px; color: #666;">已选 0 项</span>
|
|
<div style="flex: 1;"></div>
|
|
<button class="batch-btn danger" onclick="confirmBatchDeleteEmails()">
|
|
🗑️ 删除
|
|
</button>
|
|
</div>
|
|
<div class="resizer" role="separator" aria-orientation="vertical" aria-label="调整邮件列表面板宽度"
|
|
aria-valuenow="380" aria-valuemin="280" aria-valuemax="600" tabindex="0" data-resizer="emails">
|
|
</div>
|
|
</div>
|
|
|
|
<!-- 邮件详情面板(不可折叠) -->
|
|
<div class="email-detail-panel">
|
|
<div class="email-detail-toolbar" id="emailDetailToolbar" style="display:none;">
|
|
<button class="back-btn" onclick="showEmailList()">← 返回</button>
|
|
<button class="toggle-list-btn" onclick="toggleEmailList()">
|
|
<span id="toggleListText">隐藏列表</span>
|
|
</button>
|
|
<button class="fullscreen-btn" onclick="openFullscreenEmail()">🔍 全屏查看</button>
|
|
<label
|
|
style="display: flex; align-items: center; gap: 6px; font-size: 13px; margin-left: 12px; cursor: pointer;">
|
|
<input type="checkbox" id="trustEmailCheckbox" onchange="toggleTrustMode(this)">
|
|
<span style="user-select: none;">信任此邮件</span>
|
|
</label>
|
|
<div style="flex: 1;"></div>
|
|
<button class="batch-btn danger" onclick="confirmDeleteCurrentEmail()"
|
|
style="padding: 4px 8px; font-size: 12px;">
|
|
🗑️ 删除
|
|
</button>
|
|
</div>
|
|
<div id="emailDetail">
|
|
<div class="empty-state">
|
|
<div class="empty-state-icon">📄</div>
|
|
<div class="empty-state-text">选择一封邮件查看详情</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
</div>
|
|
|
|
{% include 'partials/modals.html' %}
|
|
|
|
{% include 'partials/scripts.html' %}
|
|
</body>
|
|
|
|
</html>
|