Skip to content

feat(deepseek-peak): add DeepSeek peak/off-peak bar widget - #958

Open
Alpzy wants to merge 2 commits into
noctalia-dev:mainfrom
Alpzy:feat/deepseek-peak
Open

Alpzy wants to merge 2 commits into
noctalia-dev:mainfrom
Alpzy:feat/deepseek-peak

Conversation

@Alpzy

@Alpzy Alpzy commented Sep 18, 2026

Copy link
Copy Markdown

What this adds

DeepSeek Peak Hours — a bar widget showing whether the DeepSeek API is currently billed at peak (2x) or off-peak rates.

  • Green dot off-peak, red dot at peak, amber when the published pricing policy appears to have changed.
  • Live HH:MM:SS countdown to the next rate flip in the bar; left-click opens an info panel with today's windows in local, UTC and Beijing time.
  • Peak is 01:00–04:00 and 06:00–10:00 UTC, Monday–Friday; weekends are off-peak all day, anchored to the Beijing calendar.
  • Offline-first: the schedule is bundled; the optional policy check only reads the public pricing page and warns on drift. No API key, no request metering.

Structure

  • Main.qml — shared state (schedule math, countdown), the policy-drift checker, translated strings, IPC (plugin:deepseek-peak).
  • BarWidget.qml — capsule (dot + countdown), tooltip, left-click toggles the panel, right-click opens widget settings.
  • Panel.qml — info-only panel using the registry panel contract (geometryPlaceholder, allowAttach, dynamic contentPreferredHeight).
  • Settings.qml / SettingsControls.qml — the Configure surface.
  • i18n/ — 23 locales, matching Noctalia's availableLanguages.

How to test

  1. Copy deepseek-peak/ into ~/.config/noctalia/plugins/ and enable it (tested with noctalia-shell 4.7.7 on Niri).
  2. Add the widget from Settings → Bar.
  3. Check the dot and countdown against the windows above; left-click for the panel, right-click → Widget settings.
  4. Settings persist across restarts; transient drift state is not persisted.

Notes

  • preview.png (16:9, 960x540) included.
  • The upstream source repository also carries an experimental, unpublished v5 Luau port; this PR adds only the v4 plugin.

Shows whether the DeepSeek API is billed at peak (2x) or off-peak rates:
a coloured dot and a live HH:MM:SS countdown in the bar, plus an info panel
with today's windows in local, UTC and Beijing time.

- Main.qml owns schedule state, the optional policy-drift checker and IPC.
- Peak 01:00-04:00 and 06:00-10:00 UTC Mon-Fri; weekends off-peak, anchored
  to the Beijing calendar.
- Offline-first: bundled schedule; the online check only adds an amber drift
  warning and never blanks the widget.
- 23 locales under i18n/ (Noctalia's supported language list).
@Alpzy

Alpzy commented Sep 18, 2026

Copy link
Copy Markdown
Author

Note on CI: code-quality and manifest-check fail during the Checkout repository step, before any validation runs:

Refusing to check out fork pull request code from a 'pull_request_target' workflow ... set 'allow-unsafe-pr-checkout: true'

That is the actions/checkout fork guard for pull_request_target workflows, not a result of this plugin's content. check-first-plugin-requirements and assign-reviewers pass. Happy to adjust anything on the plugin side if a maintainer can re-run the two jobs (or verify manually).

Bar and panel now compute tier/countdown locally (peak.js inlined into all
three components) and use Main.qml only for drift and last-check time, so a
missing or failed Main can never blank the widget.
@Alpzy

Alpzy commented Sep 18, 2026

Copy link
Copy Markdown
Author

Ping on the two red checks: code-quality and manifest-check both stop at Checkout repository with:

Refusing to check out fork pull request code from a 'pull_request_target' workflow ... set 'allow-unsafe-pr-checkout: true'

That is actions/checkout@v6's fork guard for pull_request_target; it fires before any validation and affects every fork PR. We can't change it from our branch. Would a maintainer mind either re-running those two jobs with allow-unsafe-pr-checkout: true on the checkout step (or pinning actions/checkout@v4) so they actually run against this PR?

For what it's worth, I checked the plugin against the rules in both workflows: the manifest has all required fields with the registry repository value and no official key, and the QML provides every required property per component (BarWidget screen/widgetId/section*, Main pluginApi, Panel geometryPlaceholder/allowAttach, Settings pluginApi) with no console.log, raw Text/Button, tr(...) || fallback, hardcoded text, or bare pixel values.

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.

1 participant