- common/Icons.ets(生成器产出):43 枚与 WebUI icons.tsx 同几何的 Path 图标 - NavItems.ts:icon(emoji) → iconKey,与 WebUI 导航同图标 - 全页面 emoji 清除(空态改单行灰字,按钮/头像/刷新等换 AmIcon) - MailDetailPage 接入 @luvi/lv-markdown-in(第三方,替代手写解析器) - WideSidebar + MainPage isWide(≥768vp):宽屏侧栏 60vp 图标轨、藏底部条、onAreaChange 断点 - 通知=可配置项(默认关):PushService.isEnabled/setEnabled + reportToken 最前 gate (关=不取token/不弹权限/不打网关)+ SettingsPage Toggle + 服务端通道状态提示 - EntryAbility.onCreate 解析 want:冷启点通知也能路由(原来只有 onNewWant) - 判据:harmony-widescreen(4) + harmony-push-optin(4) 新增;harmony-nav 同步 iconKey/条件 padding
212 lines
6.6 KiB
Plaintext
212 lines
6.6 KiB
Plaintext
/*
|
||
* AgentMail 鸿蒙客户端 — 收件箱页
|
||
* GET /me/inbox 分页,列表展示邮件摘要
|
||
*/
|
||
import { ApiClient, ApiError } from '../api/ApiClient';
|
||
import { Theme } from '../common/Theme';
|
||
import { MailApi } from '../api/MailApi';
|
||
import { MailSummary, Me } from '../model/Models';
|
||
import { router } from '@kit.ArkUI';
|
||
import { AmIcon } from '../common/Icons';
|
||
|
||
@Entry
|
||
@Component
|
||
struct InboxPage {
|
||
@State mails: MailSummary[] = [];
|
||
@State loading: boolean = false;
|
||
@State limit: number = 20;
|
||
@State total: number = 0;
|
||
@State unread: number = 0;
|
||
@State me: Me = new Me();
|
||
@State error: string = '';
|
||
|
||
private client: ApiClient | null = null;
|
||
private mailApi: MailApi | null = null;
|
||
|
||
aboutToAppear(): void {
|
||
const ctx = this.getUIContext().getHostContext();
|
||
if (ctx !== undefined) {
|
||
const client: ApiClient = ApiClient.getInstance(ctx);
|
||
this.client = client;
|
||
this.mailApi = new MailApi(client);
|
||
this.loadInbox();
|
||
}
|
||
}
|
||
|
||
async loadInbox(): Promise<void> {
|
||
const c: ApiClient | null = this.client;
|
||
const m: MailApi | null = this.mailApi;
|
||
if (c === null || m === null) {
|
||
return;
|
||
}
|
||
this.loading = true;
|
||
this.error = '';
|
||
try {
|
||
const resp = await m.inbox('all', this.limit);
|
||
this.mails = resp.mails;
|
||
this.total = resp.total;
|
||
// 客户端统计未读(API 未提供顶层 unread)
|
||
let unreadCount: number = 0;
|
||
for (let i = 0; i < this.mails.length; i++) {
|
||
if (this.mails[i].status === 'unread') {
|
||
unreadCount++;
|
||
}
|
||
}
|
||
this.unread = unreadCount;
|
||
} catch (e) {
|
||
const ae = e as ApiError;
|
||
this.error = ae.message.length > 0 ? ae.message : '加载失败';
|
||
} finally {
|
||
this.loading = false;
|
||
}
|
||
}
|
||
|
||
build() {
|
||
Column() {
|
||
// 顶栏
|
||
Row() {
|
||
Text('收件箱')
|
||
.fontSize(20).fontWeight(FontWeight.Bold).fontColor(Theme.textPrimary)
|
||
Blank()
|
||
if (this.unread > 0) {
|
||
Text(this.unread + ' 未读')
|
||
.fontSize(13).fontColor(Theme.surface)
|
||
.backgroundColor(Theme.danger)
|
||
.borderRadius(10)
|
||
.padding({ left: 8, right: 8, top: 2, bottom: 2 })
|
||
}
|
||
}
|
||
.width('100%')
|
||
.height(56)
|
||
.padding({ left: 16, right: 16 })
|
||
.backgroundColor(Theme.surface)
|
||
|
||
// 列表
|
||
if (this.loading) {
|
||
Column() {
|
||
LoadingProgress().width(40).height(40)
|
||
Text('加载中…').fontSize(14).fontColor(Theme.textSubtle).margin({ top: 8 })
|
||
}
|
||
.width('100%').height('80%')
|
||
.justifyContent(FlexAlign.Center)
|
||
} else if (this.error.length > 0) {
|
||
Column() {
|
||
Text(this.error).fontSize(14).fontColor(Theme.danger)
|
||
Button('重试').margin({ top: 12 }).onClick(() => { this.loadInbox(); })
|
||
}
|
||
.width('100%').height('80%')
|
||
.justifyContent(FlexAlign.Center)
|
||
} else if (this.mails.length === 0) {
|
||
Column() {
|
||
Text('收件箱为空').fontSize(16).fontColor(Theme.textSubtle)
|
||
}
|
||
.width('100%').height('80%')
|
||
.justifyContent(FlexAlign.Center)
|
||
} else {
|
||
List({ space: 1 }) {
|
||
ForEach(this.mails, (mail: MailSummary) => {
|
||
ListItem() {
|
||
this.MailItem(mail)
|
||
}
|
||
.height(80)
|
||
.backgroundColor(mail.status === 'unread' ? Theme.accentSoft : Theme.surface)
|
||
.onClick(() => {
|
||
this.getUIContext().getRouter().pushUrl({
|
||
url: 'pages/MailDetailPage',
|
||
params: { mail_id: mail.mail_id }
|
||
});
|
||
})
|
||
}, (mail: MailSummary) => mail.mail_id)
|
||
}
|
||
.width('100%')
|
||
.layoutWeight(1)
|
||
.divider({ strokeWidth: 1, color: Theme.border, startMargin: 16, endMargin: 16 })
|
||
}
|
||
|
||
// 底部 Tab 栏(预留系统导航栏空间)
|
||
Column() {
|
||
Row() {
|
||
Column() {
|
||
AmIcon({ iconName: 'inbox', iconSize: 20, iconColor: Theme.accent })
|
||
Text('收件箱').fontSize(11).fontColor(Theme.accent)
|
||
}
|
||
.layoutWeight(1).height('100%')
|
||
.justifyContent(FlexAlign.Center)
|
||
.backgroundColor(Theme.accentSoft)
|
||
|
||
Column() {
|
||
AmIcon({ iconName: 'chatBubble', iconSize: 20, iconColor: Theme.textMuted })
|
||
Text('会话').fontSize(11).fontColor(Theme.textMuted)
|
||
}
|
||
.layoutWeight(1).height('100%')
|
||
.justifyContent(FlexAlign.Center)
|
||
.onClick(() => {
|
||
this.getUIContext().getRouter().pushUrl({ url: 'pages/SessionsPage' });
|
||
})
|
||
|
||
Column() {
|
||
AmIcon({ iconName: 'contacts', iconSize: 20, iconColor: Theme.textMuted })
|
||
Text('联系人').fontSize(11).fontColor(Theme.textMuted)
|
||
}
|
||
.layoutWeight(1).height('100%')
|
||
.justifyContent(FlexAlign.Center)
|
||
}
|
||
.width('100%').height(56)
|
||
.backgroundColor(Theme.surface)
|
||
}
|
||
.width('100%')
|
||
}
|
||
.width('100%').height('100%')
|
||
.backgroundColor(Theme.pageBg)
|
||
}
|
||
|
||
@Builder
|
||
MailItem(mail: MailSummary) {
|
||
Row() {
|
||
// 未读圆点
|
||
Column() {
|
||
if (mail.status === 'unread') {
|
||
Circle({ width: 8, height: 8 }).fill(Theme.accent)
|
||
}
|
||
}
|
||
.width(20).height('100%')
|
||
.justifyContent(FlexAlign.Center)
|
||
|
||
// 正文
|
||
Column() {
|
||
Row() {
|
||
Text(mail.from_name).fontSize(14).fontWeight(mail.is_read ? FontWeight.Normal : FontWeight.Bold).fontColor(Theme.textPrimary)
|
||
Blank()
|
||
Text(mail.created_at).fontSize(11).fontColor(Theme.textSubtle)
|
||
}
|
||
.width('100%')
|
||
|
||
Text(mail.subject).fontSize(13).fontColor(Theme.textPrimary)
|
||
.maxLines(1).textOverflow({ overflow: TextOverflow.Ellipsis })
|
||
.margin({ top: 2 })
|
||
Text(mail.body_preview).fontSize(12).fontColor(Theme.textSubtle)
|
||
.maxLines(1).textOverflow({ overflow: TextOverflow.Ellipsis })
|
||
.margin({ top: 2 })
|
||
}
|
||
.layoutWeight(1).height('100%')
|
||
.alignItems(HorizontalAlign.Start)
|
||
.padding({ left: 8 })
|
||
|
||
// 附件图标
|
||
if (mail.has_attachments) {
|
||
AmIcon({ iconName: 'paperclip', iconSize: 14, iconColor: Theme.textMuted }).margin({ right: 8 })
|
||
}
|
||
|
||
// 权限档位徽标
|
||
if (mail.permission_mode.length > 0) {
|
||
Text(mail.permission_mode)
|
||
.fontSize(10).fontColor(Theme.textMuted)
|
||
.backgroundColor(Theme.border).borderRadius(4)
|
||
.padding({ left: 4, right: 4, top: 1, bottom: 1 })
|
||
}
|
||
}
|
||
.width('100%').height('100%')
|
||
.padding({ left: 12, right: 12 })
|
||
.alignItems(VerticalAlign.Center)
|
||
}
|
||
} |