新增了提醒静音功能,可以在设置中关闭某个日历本的提醒。
This commit is contained in:
@@ -13,6 +13,7 @@ export class AppSettings {
|
||||
private static readonly KEY_SYS_MODE: string = 'sys_cal_mode'; // 'display' | 'backup'
|
||||
private static readonly KEY_BACKUP_KEY: string = 'sys_backup_cal_key'; // 备份目标 DAV 日历本
|
||||
private static readonly KEY_MANUAL_READONLY: string = 'manual_readonly_keys'; // 手动标记只读的 calKey
|
||||
private static readonly KEY_MUTED_REMINDER: string = 'muted_reminder_keys'; // 提醒静音的 calKey
|
||||
private static readonly KEY_FULL_REFETCH: string = 'full_refetch_done'; // 一次性全量重拉已完成
|
||||
|
||||
/**
|
||||
@@ -86,6 +87,33 @@ export class AppSettings {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 提醒静音的日历本 calKey 列表。
|
||||
* 适用于别人分享的日历本:静音后其中所有日程都不再发布系统提醒(日程本身仍正常显示)。
|
||||
*/
|
||||
static async getMutedReminderKeys(context: common.Context): Promise<string[]> {
|
||||
try {
|
||||
const store: preferences.Preferences =
|
||||
await preferences.getPreferences(context, AppSettings.STORE);
|
||||
const raw: string = await store.get(AppSettings.KEY_MUTED_REMINDER, '') as string;
|
||||
return raw === '' ? [] : raw.split(';');
|
||||
} catch (err) {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
|
||||
static async setMutedReminderKeys(context: common.Context, keys: string[]): Promise<void> {
|
||||
try {
|
||||
const store: preferences.Preferences =
|
||||
await preferences.getPreferences(context, AppSettings.STORE);
|
||||
await store.put(AppSettings.KEY_MUTED_REMINDER, keys.join(';'));
|
||||
await store.flush();
|
||||
} catch (err) {
|
||||
const e = err as BusinessError;
|
||||
console.error(`保存提醒静音标记失败: ${e.message}`);
|
||||
}
|
||||
}
|
||||
|
||||
/** 系统日历模式:display = 仅混合显示;backup = 本地系统日程备份到选定 CalDAV 日历本 */
|
||||
static async getSysCalMode(context: common.Context): Promise<string> {
|
||||
try {
|
||||
|
||||
@@ -5,6 +5,7 @@ import { reminderAgentManager } from '@kit.BackgroundTasksKit';
|
||||
import { common } from '@kit.AbilityKit';
|
||||
import { BusinessError } from '@kit.BasicServicesKit';
|
||||
import { EventDb, LocalEvent } from './EventDb';
|
||||
import { AppSettings } from './AppSettings';
|
||||
import { LogUtil } from './LogUtil';
|
||||
|
||||
export class ReminderService {
|
||||
@@ -18,8 +19,13 @@ export class ReminderService {
|
||||
const now: number = Date.now();
|
||||
const rows: LocalEvent[] =
|
||||
await EventDb.queryRemindable(context, now, now + ReminderService.WINDOW);
|
||||
// 提醒静音的日历本(如别人分享的本):其中所有日程都不再提醒
|
||||
const muted: string[] = await AppSettings.getMutedReminderKeys(context);
|
||||
let published: number = 0;
|
||||
for (const e of rows) {
|
||||
if (muted.includes(e.calKey)) {
|
||||
continue;
|
||||
}
|
||||
if (published >= ReminderService.MAX_REMINDERS) {
|
||||
break;
|
||||
}
|
||||
@@ -50,7 +56,7 @@ export class ReminderService {
|
||||
await reminderAgentManager.publishReminder(request);
|
||||
published++;
|
||||
}
|
||||
LogUtil.write(`提醒刷新完成:发布 ${published} 个提醒(窗口 7 天)`);
|
||||
LogUtil.write(`提醒刷新完成:发布 ${published} 个提醒(窗口 7 天,静音日历本 ${muted.length} 个)`);
|
||||
} catch (err) {
|
||||
const e = err as BusinessError;
|
||||
LogUtil.write(`提醒刷新失败: ${e.code} - ${e.message}`);
|
||||
|
||||
@@ -5,6 +5,7 @@ import { common } from '@kit.AbilityKit';
|
||||
import { AppSettings } from '../common/AppSettings';
|
||||
import { BackgroundSyncService } from '../common/BackgroundSyncService';
|
||||
import { AccountStore, DavAccount } from '../common/AccountStore';
|
||||
import { ReminderService } from '../common/ReminderService';
|
||||
import { LogUtil } from '../common/LogUtil';
|
||||
|
||||
const INTERVAL_OPTIONS: number[] = [1, 5, 15, 30, 60];
|
||||
@@ -27,6 +28,7 @@ struct SettingsPage {
|
||||
@State backupTargets: BackupTarget[] = [];
|
||||
@State allBooks: BackupTarget[] = []; // 全部 DAV 日历本(只读标记管理用)
|
||||
@State manualKeys: string[] = []; // 手动标记只读的 calKey
|
||||
@State mutedKeys: string[] = []; // 提醒静音的 calKey
|
||||
private context?: common.Context;
|
||||
|
||||
aboutToAppear(): void {
|
||||
@@ -51,6 +53,9 @@ struct SettingsPage {
|
||||
AppSettings.getManualReadonlyKeys(ctx).then((v: string[]): void => {
|
||||
this.manualKeys = v;
|
||||
});
|
||||
AppSettings.getMutedReminderKeys(ctx).then((v: string[]): void => {
|
||||
this.mutedKeys = v;
|
||||
});
|
||||
this.loadBackupSettings();
|
||||
this.loadAllBooks();
|
||||
}
|
||||
@@ -106,6 +111,33 @@ struct SettingsPage {
|
||||
return b.serverWritable ? '可写' : '只读';
|
||||
}
|
||||
|
||||
/** 切换日历本提醒静音:静音后该本所有日程不再发布系统提醒 */
|
||||
private async toggleMuteBook(b: BackupTarget): Promise<void> {
|
||||
if (this.context === undefined) {
|
||||
return;
|
||||
}
|
||||
const list: string[] = [...this.mutedKeys];
|
||||
const idx: number = list.indexOf(b.calKey);
|
||||
if (idx >= 0) {
|
||||
list.splice(idx, 1);
|
||||
} else {
|
||||
list.push(b.calKey);
|
||||
}
|
||||
this.mutedKeys = list;
|
||||
await AppSettings.setMutedReminderKeys(this.context, list);
|
||||
// 立即重建提醒(全量取消后按新静音规则重发),无需等下次同步
|
||||
try {
|
||||
await ReminderService.refreshReminders(this.context as common.UIAbilityContext);
|
||||
} catch (err) {
|
||||
// 重建失败不影响设置保存,下次同步时会再刷新
|
||||
}
|
||||
this.getUIContext().getPromptAction().showToast({
|
||||
message: idx >= 0
|
||||
? '已恢复提醒'
|
||||
: '已静音:该日历本的所有日程不再提醒'
|
||||
});
|
||||
}
|
||||
|
||||
/** 加载备份目标候选(可写 DAV 日历本)+ 当前选择 */
|
||||
private async loadBackupSettings(): Promise<void> {
|
||||
if (this.context === undefined) {
|
||||
@@ -379,6 +411,59 @@ struct SettingsPage {
|
||||
.backgroundColor($r('app.color.card_bg'))
|
||||
.border({ width: 1, color: $r('app.color.shadow_color') })
|
||||
|
||||
// 日历本提醒静音(如别人分享的日历本,静音后其中所有日程不再提醒)
|
||||
Column({ space: 8 }) {
|
||||
Row({ space: 10 }) {
|
||||
Column({ space: 2 }) {
|
||||
Text('日历本提醒静音')
|
||||
.fontSize(15)
|
||||
.fontWeight(FontWeight.Medium)
|
||||
.fontColor($r('app.color.text_primary'))
|
||||
Text('点击日历本切换静音:静音后该日历本的所有日程都不再提醒(日程仍正常显示)')
|
||||
.fontSize(12)
|
||||
.fontColor($r('app.color.text_secondary'))
|
||||
}
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
.layoutWeight(1)
|
||||
}
|
||||
.width('100%')
|
||||
if (this.allBooks.length === 0) {
|
||||
Text('暂无 CalDAV 日历本')
|
||||
.fontSize(12)
|
||||
.fontColor($r('app.color.text_hint'))
|
||||
.width('100%')
|
||||
}
|
||||
ForEach(this.allBooks, (b: BackupTarget) => {
|
||||
Row({ space: 8 }) {
|
||||
Text(b.label)
|
||||
.fontSize(13)
|
||||
.fontColor($r('app.color.text_primary'))
|
||||
.maxLines(1)
|
||||
.textOverflow({ overflow: TextOverflow.Ellipsis })
|
||||
.layoutWeight(1)
|
||||
Text(this.mutedKeys.includes(b.calKey) ? '已静音' : '提醒中')
|
||||
.fontSize(11)
|
||||
.fontColor(this.mutedKeys.includes(b.calKey)
|
||||
? $r('app.color.error') : $r('app.color.success'))
|
||||
.padding({ left: 8, right: 8, top: 3, bottom: 3 })
|
||||
.borderRadius(10)
|
||||
.backgroundColor(this.mutedKeys.includes(b.calKey)
|
||||
? $r('app.color.error_bg') : $r('app.color.success_bg'))
|
||||
}
|
||||
.width('100%')
|
||||
.padding({ top: 6, bottom: 6 })
|
||||
.onClick(() => {
|
||||
this.toggleMuteBook(b);
|
||||
})
|
||||
}, (b: BackupTarget) => `mute_${b.calKey}_${this.mutedKeys.includes(b.calKey) ? 1 : 0}`)
|
||||
}
|
||||
.alignItems(HorizontalAlign.Start)
|
||||
.width('100%')
|
||||
.padding(14)
|
||||
.borderRadius(12)
|
||||
.backgroundColor($r('app.color.card_bg'))
|
||||
.border({ width: 1, color: $r('app.color.shadow_color') })
|
||||
|
||||
// 数据修复:手动触发一次性全量重拉(重建提醒等本地残缺字段)
|
||||
Row({ space: 10 }) {
|
||||
Column({ space: 2 }) {
|
||||
|
||||
Reference in New Issue
Block a user