Skip to content

feat(notify): user-notify 桌面通知与点击深链 - #158

Open
SoloJiang wants to merge 12 commits into
mainfrom
feat/system-notifications-user-notify
Open

feat(notify): user-notify 桌面通知与点击深链#158
SoloJiang wants to merge 12 commits into
mainfrom
feat/system-notifications-user-notify

Conversation

@SoloJiang

Copy link
Copy Markdown
Owner

Summary

  • 用社区 user-notify 替换官方 @tauri-apps/plugin-notification 的桌面发送路径,支持点击深链(notify://open → issue / direction / Needs-you / Resources)
  • 补齐通知产品面:分类开关(needs/review/stalled/quota)、免打扰时段、Dock badge、失焦门闩、stalled/quota 事件
  • 纯函数与路由意图可单测(notificationsCore + planNotifyOpen

Why

官方插件桌面端没有可靠 click/action 回调(plugins-workspace#2150)。社区 user-notify(Delta Chat Tauri 路线)直接走系统 API,可携带 user_info 并在点击时回传。

Verification

  • node --test --experimental-strip-types tests/frontend/notifications.test.ts(15 passed)
  • pnpm exec tsc --noEmit
  • CARGO_TARGET_DIR=... cargo test os_notify(roundtrip unit tests passed; crate compiles)

Notes

  • macOS 真机点击深链请以签名 release 包为准;tauri dev 未签名时 user-notify 可能退到 mock。
  • 官方 notification plugin 仍保留 capability 兼容,但前端发送已切到 os_notify_* 命令。

用社区 user-notify 替换官方插件发送路径,支持点击跳转;补齐分类开关、免打扰、stalled/quota 事件与 Dock badge。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 95df1b6257

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/state/store.tsx Outdated
Comment thread src/lib/notificationsCore.ts Outdated
Comment thread src/lib/notificationsCore.ts Outdated
Comment thread src-tauri/src/os_notify.rs Outdated
Comment thread src-tauri/src/os_notify.rs
Comment thread src/lib/notificationsCore.ts Outdated
Comment thread src/lib/notificationsCore.ts Outdated
修复误删的 Needs-you 轮询/事件监听;补齐 write-trigger/action-required 路由、workspace 归属、stalled session 精确定位、权限 denied 记忆与冷启动 pending click。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 13a921a10f

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src-tauri/src/os_notify.rs Outdated
Comment thread src-tauri/src/os_notify.rs Outdated
Comment thread src/lib/notifications.ts Outdated
Comment thread src/lib/notificationsCore.ts Outdated
Comment thread src/lib/notifications.ts Outdated
修复 workspace 切换竞态、pending click 重放、权限缓存遮挡系统恢复,以及 Dock badge 跨 workspace 计数;stalled 文案去掉硬编码英文词。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 6371276654

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/lib/notifications.ts Outdated
Comment thread src/lib/notificationsCore.ts
Comment thread src/lib/notifications.ts Outdated
Comment thread src/lib/notifications.ts Outdated
Comment thread src-tauri/src/os_notify.rs Outdated
后端 pending 命令返回 Result;前端信任 denied 状态、避免 badge 重复计数,拆分 live/pending 监听,并用跨 workspace 线程索引修正全局通知归属。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 270ae677e9

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/state/store.tsx Outdated
selectWorkspace 加载线程时误递归调用 helper 导致栈溢出,改为 setThreads + 更新 workspace 索引。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 305c6dc684

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src-tauri/src/os_notify.rs
点击通知时 unminimize/show/focus 失败不再静默吞掉,改为显式日志,避免看起来像点击无响应。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 43a9a5be75

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/lib/notifications.ts
跨 workspace 点击通知时,等 selectWorkspace 完成加载后再消费 pending 路由,避免异步 reset 清掉目标视图。
补挂 workspaceLoadSeq 到 context value,供通知深链等待 workspace 加载完成。

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: d9b11e1d8a

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/lib/notifications.ts
Comment thread src/lib/notificationsCore.ts Outdated
Comment thread src/lib/notifications.ts
- workspace_needs_counts includes notice_action_required for dock/switcher badges
- quota routes omit workspace switches so Resources stays process-global
- openSettings no longer resnapshots when Settings is already open; live page via settingsRequestedPage
@SoloJiang

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: ed03adcabc

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/lib/notifications.ts
Comment thread src/nav/SettingsDialog.tsx
Comment thread src/lib/notificationsCore.ts Outdated
Comment thread src/lib/notifications.ts Outdated
Comment thread src/lib/notificationsCore.ts
- wait for both selectWorkspace load seq bumps before applying cross-workspace routes
- settings deep links use a seq token so repeated Resources clicks re-apply
- stalled routes require owning workspace; curator stalls open Repo Map curator
- restore pending OS click when StrictMode cancels the first cold-start drain
@SoloJiang

Copy link
Copy Markdown
Owner Author

@codex review

1 similar comment
@SoloJiang

Copy link
Copy Markdown
Owner Author

@codex review

CI failed because user_info helpers referenced open_curator without the struct fields.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: cf88f87777

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/lib/notifications.ts
openCurator now clears issue/worker overlays and switches homeTab to repos so the curator panel is actually visible.
@SoloJiang

Copy link
Copy Markdown
Owner Author

@codex review

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 778b6899a7

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread src/lib/notifications.ts
Comment on lines +220 to +224
if (
workspaceIntent &&
workspaceIntent.type === "workspace" &&
workspaceIntent.workspaceId !== deps.activeWorkspaceId
) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Defer clicks while the target workspace is still loading

When a notification targets the workspace already present in activeWorkspaceId while selectWorkspace is still loading it—such as during cold-start restoration or a manual switch—this condition skips deferral and applies the deep link immediately. The in-flight selectWorkspace subsequently clears activeThreadId, showNeeds, and homeTab, undoing the notification navigation; defer based on workspace loading completion even when the IDs already match.

Useful? React with 👍 / 👎.

Comment on lines +239 to +245
Ok(false) => {
if let Ok(guard) = perm_settled().lock() {
if guard.as_deref() == Some("denied") {
return Ok("denied".to_string());
}
}
Ok("prompt".to_string())

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Report revoked notification permission as denied

If permission was previously granted and the user later revokes it in the OS while Weft remains running, the native query returns false while PERM_SETTLED still contains "granted", so this branch reports "prompt" rather than "denied". Because Settings only offers the System Settings recovery link for denied, the user sees notifications enabled without the repair action until another permission request happens; handle a false result after a prior grant as revocation or otherwise persist/query the actual authorization state.

Useful? React with 👍 / 👎.

Comment on lines +223 to +225
for (const a of asks) {
const directionId = Number(a.dir);
const ws = threadsById[a.thread]?.workspaceId ?? workspaceId ?? undefined;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Avoid assigning global asks to the selected workspace

For a permission ask belonging to a workspace that has not been visited in the current frontend session, pendingAsks() still includes the ask globally but threadsById has no metadata for its thread. This fallback therefore stamps the currently selected workspace onto the notification, so clicking it remains in or switches to the wrong workspace instead of the ask's owning issue; omit the workspace when unknown or obtain the ownership from backend data rather than using the active workspace.

Useful? React with 👍 / 👎.

Comment on lines +273 to +278
const meta = threadsById[s.threadId];
// Global live sessions may predate a visit to their workspace; prefer the
// session's own workspace, then thread metadata. Never fall back to the
// currently selected workspace for global stalled workers.
const ws = s.workspaceId ?? meta?.workspaceId;
if (ws == null) continue;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Carry workspace ownership for adopted stalled workers

A boot-revived worker can belong to a workspace the user has not visited, but the actual OpenSession and backend LiveWorkerSlot shapes never populate the optional workspaceId read here. With no cached threadsById entry either, this branch drops the stalled worker entirely, so the newly added stalled notification is never emitted for precisely those background workers; include workspace ownership in the adopted slot/session or load a global thread-to-workspace mapping.

Useful? React with 👍 / 👎.

Comment thread src/lib/notifications.ts
Comment on lines 515 to 518
const base = baselineWs.current === activeWorkspaceId ? prev.current : null;
prev.current = next;
baselineWs.current = activeWorkspaceId;
if (!base) return; // first load / workspace switch: baseline only

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Establish the baseline after notification state hydrates

On a background WebView reload, this first pass records an empty snapshot before the store's asynchronous quota refresh and worker/Needs hydration finish. If the backend is already degraded when processQuota arrives, for example, the next pass treats that pre-existing state as a fresh transition and emits a quota notification even though the comment promises first load is silent; defer baseline completion until the initial notification sources have settled or independently baseline each source on its first value.

Useful? React with 👍 / 👎.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants