Skip to content

Releases: goccx/GotifyDesktop

v0.2.19

Choose a tag to compare

@goccx goccx released this 01 Nov 18:24

Performance & Stability (macOS 12+)

  • Zero-T0-Teardown Sidebar Switching (InboxView): Keep displayPage bound to readyPage on Frame T0 (isTransitioning == true) while hiding the underlying MessageListView via .opacity(0) and presenting ProgressView overlay. Frame T0 no longer unmounts or diffs the previous 100-row NSTableView inside mouseDown.
  • Defer Uncached Table Swap Until REST Completion (InboxView): When switching to an uncached category, keep readyPage unchanged while the .loading overlay is shown until loadMessages returns, so clicking across uncached categories performs zero intermediate NSTableView teardowns or rebuilds.
  • Settle-Guarded & Scroll-Driven Incremental Row Mounting (MessageListView): Mount the initial 15-row viewport (< 3ms), expand immediately if the user scrolls near the bottom of mounted rows, and wait a 100ms settle interval before expanding off-screen rows in 20-row slices so rapid sidebar navigation only ever tears down 15 rows (< 2ms).
  • Deterministic Load Cancellation (GotifySessionController): Immediately reset a cancelled page load's .loading state on MessageStore before starting the next page load, preventing async Alamofire cancellation from racing with rapid A -> B -> A reselection.
  • Pre-Resolved Localization Bundles (Localized) & Static Icon Fallback (GotifyApplicationIcon): Retain "en" and "zh-Hans" Bundle instances as static constants and skip LazyImage (@StateObject FetchImage) when url == nil.

Checksums (SHA-256)

  • GotifyDesktop-macOS-arm64.dmg: 0071392e25a7578351501e989b08bd9a04fa026b4b8622d6f56e65f4573bf91e
  • GotifyDesktop-macOS-amd64.dmg: ffdbdc659ca195d8d29a7674153f3c8959557c4b27a99f300f4bc9124af579da

v0.2.18

Choose a tag to compare

@goccx goccx released this 01 Nov 17:57

v0.2.18

Fixed & Changed

  • 真正跨帧提交 T0(消除 DispatchQueue.main.async 同帧合并阻塞):
    • 使用 RunLoop.main .common 模式 0 秒 Timer(带 withTaskCancellationHandler 即时取消),严格在当前事件周期 kCFRunLoopBeforeWaiting 将 T0 帧(左侧选中高亮 + 加载态)提交给屏幕之后再进入 T1,彻底避免 T0 与 T1 被合并到同一次主线程同步事务。
  • macOS 12 列表加载两阶段渐进挂载(T1 先挂 15 条视口行,T2 补齐全部行):
    • 列表挂载首帧仅测量并渲染首屏可见的 15 行(耗时 < 10ms),随后在 .task(id: page) 下一帧自动放开至全部行(保证滚动条与尾部分页 100% 完整);若在加载或挂载中途切换侧栏,.task 自动取消,绝不阻塞新点击。
  • 控制器层独占取消未完成的页面网络请求:
    • GotifySessionController 维护唯一 activePageLoadTask,切走时立即取消前一个未完成分类的底层网络请求。
  • 列表行标题与摘要彻底脱离主线程 AttributedString(markdown:):
    • plainTextSummary 与 listRowSummaryText 采用单遍纯字符流去标记算法(stripInlineMarkdownToPlainText),列表行挂载 0 次调用 CommonMark 富文本解析器。

Checksums (SHA-256)

bab56f66e94e674f9d7223b5383f99f010ef11337c6f8015920adee4c712eaeb  GotifyDesktop-macOS-arm64.dmg
ed31f617710c2b5193eabb5ebb1949d91fbbc362f5f37424f5a5f33bef0488f7  GotifyDesktop-macOS-amd64.dmg

v0.2.17

Choose a tag to compare

@goccx goccx released this 01 Nov 17:46

v0.2.17

Fixed & Changed

  • T0 侧栏切换绝对优先(任何加载中或过渡中的列表绝不阻挡切换):
    • 废除 CATransaction.setCompletionBlock(macOS 12 下会在 ProgressView 或连续点击时被系统覆盖导致卡在加载态),统一使用下一轮主队列调度并绑定可取消的 pageSwitchTask;
    • 切换离开仍在网络请求中的未加载分类时,自动取消该请求并归位为 .idle,不会阻塞当前分类或误置为 .failed。
  • macOS 12 列表行零额外内存提速:
    • 行内时间使用静态 Text 替代每行独立 TimelineView 定时器;
    • 行内删除按钮仅在悬停/激活时挂载 Button 与 .onHover;
    • 行内 2 行摘要使用纯文本 listRowSummaryText(不向 GotifyMessage 增加任何存储字段,0 额外内存,消除 NSTableView 测量行高时的 AttributedString 桥接开销);
    • .onAppear / .onDisappear 可见行上报按严格时间顺序数组 [(page, messageID, visible)] 合并为单次 Actor 调用,消灭切换时主线程 200 个 Task 排队,同时 100% 保持原版尾段内存裁剪顺序。

Checksums (SHA-256)

7b693c64ec6b978bae657e7a144b61e79dcaa57c7389438efb8cb6cf6c46e78f  GotifyDesktop-macOS-arm64.dmg
134d5f621ce8e5d3e8112fc4177d24ced0096065b544bac9597942e1c40f4657  GotifyDesktop-macOS-amd64.dmg

v0.2.16

Choose a tag to compare

@goccx goccx released this 01 Nov 17:29

v0.2.16

Changed

  • Markdown 摘要与行内解析纯算法优化:
    • plainTextSummary 对单行无 Markdown 语法文本走 UTF-8 字节级短路,并以 split(whereSeparator: \.isWhitespace).joined(separator: " ") 替代每次调用 NSRegularExpression;
    • inlineAttributedString / summaryAttributedString 对无行内 Markdown 触发符的文本直接构造 AttributedString,跳过 cmark 语法树解析;
    • sanitizeMarkdownLinks 在不含 [ 时直接返回原字符串,避免无条件构造 [Character] 数组;
    • applyRemainingBoldSpans 仅在包含字面量 ** 时扫描对应 run;
    • collapseBlockSyntaxForSummary 对超长日志/正文限制前 24 个非空行(或 2 KB),避免为 2 行列表预览全量解析整篇长消息。
  • 完整保持 v0.2.6 业务、并发、内存与视图逻辑:InboxView、GotifyMessage、GotifyMessagePageStore、MessageStore、GotifyRESTClient、RelativeTimeLabel、MacOSCompatibility 与 v0.2.6 保持完全一致。

Checksums (SHA-256)

e1e338a3d47166a9eab871da349bef8414bbd4a594bb2398ebb551e0df18293b  GotifyDesktop-macOS-arm64.dmg
e829680ca0664a2b9bd61665d9856f0123da03aed0a599e1ac4f7085e890e417  GotifyDesktop-macOS-amd64.dmg

v0.2.15

Choose a tag to compare

@goccx goccx released this 01 Nov 16:56

v0.2.15 (49a9ee5)

优化与修复

  • 列表行视图减负与可见性回调合并(零侵入滚动条与内存规则):
    • 列表行相对时间改用静态文本渲染,移除每行独立的 TimelineView 定时器;
    • 行尾删除按钮改为 if isVisible 按需挂载,未悬停行不再实例化隐藏的 NSButton 与 .onHover 追踪区;
    • 合并切换分类时的行可见性回调(200 次独立 Task 合并为单次批量 Actor 更新)。
  • 关于面板显示 Git Commit 短 ID:版本 0.2.15 (49a9ee5)。

SHA-256

  • GotifyDesktop-macOS-arm64.dmg: 153e030b5f57ae935781eda755322c86844988db38bc39426e499c68778360cb
  • GotifyDesktop-macOS-amd64.dmg: 485b89a73a4c79d13a83da20b3ecb28ca649f05c84ff820859bf33c52b4e2c84

v0.2.14

Choose a tag to compare

@goccx goccx released this 01 Nov 16:48

v0.2.14 (12f0d47)

修复与调整

  • macOS 12 侧边栏收起按钮采用社区标准 ToolbarItem(placement: .navigation):
    • macOS 13+ 使用原生 NavigationSplitView;
    • macOS 12 使用 NavigationView + ToolbarItem(placement: .navigation) 标准实现,展开与收起均遵循 macOS 12 原生工具栏布局(不跑去右侧主操作区、收起时推开标题不重叠)。
  • 关于面板显示 Git Commit 短 ID:版本 0.2.14 (12f0d47)。

SHA-256

  • GotifyDesktop-macOS-arm64.dmg: aa5f953558d6ee2ab0b52199d39123c0b5d471787abb1a0f3d6ffdc41db9f06b
  • GotifyDesktop-macOS-amd64.dmg: 02a935698db7941a05e98e0eeebbe6b9ce9b862ebea1c92119e5c5a88270b61a

v0.2.13

Choose a tag to compare

@goccx goccx released this 01 Nov 16:35

v0.2.13 (b6894f1)

修复与还原

  • 完整还原列表、滚动条与按需加载逻辑(回退至 v0.2.6 定稿行为):移除 displayLimit 截断、槽位索引、自动行高覆盖及后台预加载,恢复完整内存列表滚动与底部分页哨兵行为,保留后台预计算行标题/摘要。
  • macOS 12 侧边栏收起按钮采用标准 SwiftUI sidebar.toolbar:挂载在 NavigationView 左侧 sidebar 列上,展开与收起均位于左侧边栏顶部,收起时自动推开分类标题不重叠。
  • 关于面板显示 Git Commit 短 ID:版本 0.2.13 (b6894f1)。

SHA-256

  • GotifyDesktop-macOS-arm64.dmg: 70bcb74c2a3e6028238b1f01bc642a43ecaa1d24efecf91c1460d28c0a73dfea
  • GotifyDesktop-macOS-amd64.dmg: 149b628e731e16f098b88dd7e380565fc774e7136ed994ebf601811a58e7a8cb

v0.2.12

Choose a tag to compare

@goccx goccx released this 01 Nov 15:12

Gotify Desktop v0.2.12 (d466eb8)

修复与优化

  • 关于面板显示 Commit 短 ID:Tools/build-app.sh 打包时自动将当前 Git 7 位短 Commit ID (d466eb8) 写入 CFBundleVersion,点开「关于 Gotify Desktop」即可直接查看 版本 0.2.12 (d466eb8)。
  • macOS 12 切换分类卡顿根治(保留零残影 Loading):
    • MessageListView 采用固定槽位索引 (0..<20, IndexedTimelineSlot) 替代按消息 ID 重建行标识,切换分类时 macOS 12 ListCoreTableView 原地复用已挂载的 20 个 NSHostingView 单元格,0 行销毁、0 行新建,滚动到底部再按需追加。
    • 启动加载完「全部消息」后后台预热加载各应用分类消息缓存,切换分类时既严格保持第 0 帧进入 .loading 隐藏旧列表(零旧消息残影),又消除了首次点击时的网络等待与 NSHostingView 重建卡顿。
  • macOS 12 / 13+ 侧边栏收起按钮固定在左侧边栏顶部:
    • macOS 13+ 使用原生 NavigationSplitView,侧边栏按钮位于左侧红黄绿按钮旁;
    • macOS 12 在窗口左侧标题栏 (zoomButton 右侧 x ≈ 82pt) 挂载原生侧边栏收起按钮,不再跑到右侧分类标题旁边。

SHA-256

  • GotifyDesktop-macOS-arm64.dmg: c6972518297af40df4b930a32d143a6c12a65890ce348a5c3d3e4b0ed21dd960
  • GotifyDesktop-macOS-amd64.dmg: 6dd3a3cded265c0124c1aafc46883b8feb2600f89c896d1c2149cb85cd53dce9

v0.2.11

Choose a tag to compare

@goccx goccx released this 01 Nov 14:48

Gotify Desktop v0.2.11

Fixes

  • Sidebar Toggle Button Position Restored (MacOSCompatibility.swift, InboxView.swift, MenuBarContentView.swift):
    • Restored NavigationSplitView on macOS 13+ so the sidebar toggle button resides natively in the left sidebar header (relX ≈ 87pt, next to the window traffic lights) instead of beside the detail title.
    • On macOS 12 (NavigationView), repositioned the navigation toolbar item before NSTrackingSeparatorToolbarItem (index 0) so it also resides in the left sidebar header rather than next to the detail title.
  • Includes all v0.2.10 performance & zero-ghosting fixes:
    • Persistent NSTableView reuse across category switches with immediate Frame T0 .loading display (zero old-message ghosting).

SHA-256 Checksums

  • GotifyDesktop-macOS-arm64.dmg: 520af3f3b842766ac84161cb19debe0f971372cc4540bfb90d332c66262b2f5f
  • GotifyDesktop-macOS-amd64.dmg: caaf4c34cb46118620d75c73b5c2d1c7f74618fac2c5415b0a639dda1df9f1d6

v0.2.10

Choose a tag to compare

@goccx goccx released this 01 Nov 13:30

Gotify Desktop v0.2.10

Fixes & Performance Improvements (macOS 12–15+)

  • Zero Old-Message Ghosting & Persistent NSTableView Reuse (InboxView):
    • Frame T0 immediately hides the message list (opacity(0)) and displays .loading (ProgressView) so old messages from the previous category never linger on screen.
    • Kept a single persistent MessageListView (NSTableView) mounted inside ReadingCanvas across category switches (removing whole-table .id(page) teardown and avoiding 100 -> 0 -> 100 row deletion/re-insertion), preserving the NSHostingView cell reuse pool on macOS 12.
    • Set tableView.rowHeight = 84 so AppKit's usesAutomaticRowHeights estimates ~10 visible rows per viewport instead of 50+ rows on macOS 12.
  • Row Rendering & Visibility Coalescing:
    • Coalesced SwiftUI .onAppear / .onDisappear visibility callbacks on @MainActor into a single batched actor update per frame.
    • Precomputed GotifyMessage.listSummary as plain text (String) and removed per-row TimelineView instances and redundant tooltip tracking areas.
  • Window Close & Status Bar Lifecycle Preserved:
    • Clicking the red close button (X) hides the main window and switches NSApp to .accessory policy (hiding the Dock icon), while reopening from the status bar or kAEReopenApplication restores .regular policy.

SHA-256 Checksums

  • GotifyDesktop-macOS-arm64.dmg: 859484f8b41783e24ba93343d25f487df394a67aa75cb7b1d1142f807c443df2
  • GotifyDesktop-macOS-amd64.dmg: ca6534b46ed0bac21e335566806a912c67044a5796bbcf8485e00fc3d2905557