Commit Graph
1714 Commits
Author SHA1 Message Date
Donkie ff514b2c38 fix(labels): let the print dialog pick sheet orientation, clamp migrated margins
Two more problems from #1149.

Sheet mode set @page size to the paper's exact dimensions. A 62x34 page makes
the browser send it as landscape, and Chromium hides the orientation picker
when the page CSS sets a size. Label printer drivers disagree on which way
round a roll is: a Brother QL needed landscape, a Niimbot B1 needed portrait,
so any fixed choice prints rotated for someone. Sheet mode now uses size: auto
like v1 did, and the page is still laid out in mm. Label mode keeps its exact
size.

The v1 migration derived the label size from the raw margins. v1 users paired
-20mm margins with a 1.5mm printer margin to pull an oversized cell back onto a
62x34 page, which migrated as a 102x74 label. Margins are now clamped at
migration; the safe-zone alone gives the same content inset (max(safe, margin)
in both versions), and the label comes out at the paper size.
2026-09-13 10:55:12 +02:00
Donkie f229fd5afe ci: skip the duplicate pull_request run for same-repo branches
Now that every branch builds on push, opening a PR from one ran the whole
workflow twice for the same commit.

Concurrency cannot dedupe these: push and pull_request carry different refs, and
forcing them into one group only races them, killing whichever run started
first. That is the wrong outcome roughly half the time, since publish-images
runs on push and not on pull_request, so the branch image would vanish.

Guard the three jobs that have no `needs` instead. A skipped dependency skips its
dependents, so this cascades to all twelve. Forks are unaffected: a fork's push
fires no event in this repo, so its pull_request run is the only one there is.
2026-09-09 21:34:21 +02:00
Donkie 9a4dc0d8eb ci: build every branch and publish it to GHCR under the branch name
Branch pushes matched no trigger, so an unmerged fix could not be handed to a
bug reporter as an image. Push now covers all branches except weblate (constant
locale-only commits) and dependabot (arrives as PRs anyway).

publish-images was already gated only on "not a pull request", so it picks
branch pushes up for free; it just had no tag to publish them under. Adding
type=ref,event=branch to the GHCR metadata gives one, skipping master since that
is already :edge. Docker Hub deliberately keeps only edge and tagged releases,
so users browsing it do not see half-finished branches.

Concurrency now cancels superseded runs on any ref except master and tags, which
publish images and must not be interrupted mid-manifest.

Note: once a branch has an open PR, push and pull_request both fire and it runs
twice.
2026-09-09 21:27:52 +02:00
Donkie 7e69369483 fix(labels): keep sheet-printed labels at the right size and shape
Two bugs in the sheet-mode safe-zone inset, both reported in #1149.

The label raster has a fixed aspect ratio, but labelImg sized its width and
height independently, so a safe-zone squashed the label (1.5mm top/bottom on a
34mm label is a 9% vertical squeeze). v1 padded a box of reflowing HTML, where
that was harmless; a raster has to scale uniformly, so the inset box now gets
object-fit: contain.

Negative page margins made it much worse. v1 accepted them and used them to size
the grid cells; in v2 the label size comes from the design and the margin only
positions an absolutely placed grid inside an overflow:hidden page, so a negative
margin can only clip. It also inflated overSafe (safe - margin), which turned a
1.5mm safe-zone into a 21.5mm inset: at margin -20 the label rendered 22x12mm in
the corner of a 62x34mm page, and sheetGrid invented a second row off the paper.

Margins are now clamped to zero on read, so existing presets carrying v1's
negative values are fixed without the user editing them, and the margin inputs
refuse new negative values.
2026-09-09 21:15:12 +02:00
Donkie 348499f469 Tag issues opened by sponsors
The Supporter tier promises that issues a sponsor opens get an exclusive tag
so they surface first.

The sponsorship lookup is viewer-relative, so it runs on the PAT rather than
GITHUB_TOKEN, whose viewer is the Actions bot that nobody sponsors. Reading
privacyLevel needs that token's read:user scope.

Private sponsors are skipped. The label is public and applying it would
disclose a sponsorship they chose to keep hidden.
2026-09-02 17:59:16 +02:00
Donkie d34fb88b31 chore: update sponsors image 2026-09-02 15:48:39 +00:00
Donkie 798d8b1ded chore: update sponsors image 2026-09-01 20:32:50 +00:00
Donkie f8ffaa0837 Push the sponsors image with the PAT 2026-09-01 22:32:29 +02:00
Donkie 789b7fd88f Render a sponsors board in the README
A nightly workflow runs sponsorkit against the GitHub Sponsors API and commits
.github/media/sponsors.svg when it changes, so the board stays current without
any manual work.

Ko-fi has no API to query, so tips that arrive there are kept in a small
hand-maintained list in the config and fed in through a custom provider. A tip
counts toward a tier for 30 days and then drops to Past Sponsors on its own,
which is how sponsorkit treats real Ko-fi tips and how a one-time GitHub
sponsorship ages out. marko-p's $10 tip is the first entry.
2026-09-01 21:21:20 +02:00
github-actions[bot] 5424a638b1 Merge pull request #1132 from Donkie/weblatev2
Translations update from Hosted Weblate
2026-09-01 16:07:57 +00:00
Samuel Wang c281114c6f Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (600 of 600 strings)

Translation: Spoolman/Spoolman Web UI v2
Translate-URL: https://hosted.weblate.org/projects/spoolman/spoolman-web-ui-v2/zh_Hans/
2026-09-01 18:03:07 +02:00
Julia 9566f7848d Translated using Weblate (Polish)
Currently translated at 100.0% (600 of 600 strings)

Translation: Spoolman/Spoolman Web UI v2
Translate-URL: https://hosted.weblate.org/projects/spoolman/spoolman-web-ui-v2/pl/
2026-09-01 18:03:05 +02:00
Donkie 4f9cc1b75d Merge pull request #1120 from Niko11111/feat/last-uid-per-reader
Offer the reader's last UID in the Add tag dialog
2026-08-29 18:34:56 +02:00
github-actions[bot] 42721c7ebc Merge pull request #1125 from Donkie/weblatev2
Translations update from Hosted Weblate
2026-08-27 05:51:16 +00:00
github-actions[bot] d1dc40b3cc Merge pull request #1126 from Donkie/weblate
Translations update
2026-08-27 05:51:07 +00:00
Samuel Wang 92be2975b8 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (293 of 293 strings)

Co-authored-by: Samuel Wang <imhsaw@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/spoolman/web-client/zh_Hans/
Translation: Spoolman/Web Client LEGACY
2026-08-27 07:46:37 +02:00
darkk-k1 a62e4ce6c1 Translated using Weblate (Polish)
Currently translated at 100.0% (293 of 293 strings)

Co-authored-by: darkk-k1 <softdev@darkabo.eu>
Translate-URL: https://hosted.weblate.org/projects/spoolman/web-client/pl/
Translation: Spoolman/Web Client LEGACY
2026-08-27 07:46:37 +02:00
Julia 0a3404cefe Translated using Weblate (Polish)
Currently translated at 100.0% (293 of 293 strings)

Co-authored-by: Julia <juliazero2@gmail.com>
Translate-URL: https://hosted.weblate.org/projects/spoolman/web-client/pl/
Translation: Spoolman/Web Client LEGACY
2026-08-27 07:46:37 +02:00
Samuel Wang c2002e43f7 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 100.0% (598 of 598 strings)

Translation: Spoolman/Spoolman Web UI v2
Translate-URL: https://hosted.weblate.org/projects/spoolman/spoolman-web-ui-v2/zh_Hans/
2026-08-27 07:46:19 +02:00
github-actions[bot] 85e3ac7163 Merge pull request #1123 from Donkie/weblatev2
Translations update from Hosted Weblate
2026-08-26 16:16:46 +00:00
Samuel Wang 33aa3de515 Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 28.4% (170 of 598 strings)

Translation: Spoolman/Spoolman Web UI v2
Translate-URL: https://hosted.weblate.org/projects/spoolman/spoolman-web-ui-v2/zh_Hans/
2026-08-26 17:51:02 +02:00
Julia e238592e4d Translated using Weblate (Polish)
Currently translated at 100.0% (598 of 598 strings)

Translation: Spoolman/Spoolman Web UI v2
Translate-URL: https://hosted.weblate.org/projects/spoolman/spoolman-web-ui-v2/pl/
2026-08-26 17:51:00 +02:00
Micha 107a134da8 Translated using Weblate (German)
Currently translated at 100.0% (598 of 598 strings)

Translation: Spoolman/Spoolman Web UI v2
Translate-URL: https://hosted.weblate.org/projects/spoolman/spoolman-web-ui-v2/de/
2026-08-26 17:50:58 +02:00
github-actions[bot] 3cf7a9fa61 Merge pull request #1121 from Donkie/weblatev2
Translations update from Hosted Weblate
2026-08-26 09:38:35 +00:00
Zack zhou (WeAPoN.Z) 1e5b28ab7d Translated using Weblate (Chinese (Simplified Han script))
Currently translated at 26.0% (156 of 598 strings)

Translation: Spoolman/Spoolman Web UI v2
Translate-URL: https://hosted.weblate.org/projects/spoolman/spoolman-web-ui-v2/zh_Hans/
2026-08-26 11:33:46 +02:00
Niko11111 035922b49f style(tags): give the last-seen offer the weight of an action
It sat in the same quiet link style as the phone reader, which is an
alternative route rather than the thing to press. Same 600 as a UID gets
elsewhere in the tag UI, and no wrapping between verb and object.
2026-08-26 08:40:39 +02:00
Niko11111 eced7f22db feat(tags): offer what the reader already has in the Add tag dialog
The dialog waits for a fresh tap, which is right for a sticker in your hand and
awkward for a reader that already holds the tag. On a scale the spool is on the
pad to be weighed, so filling in the field means lifting it off and putting it
back; from the user's side that looks like the dialog not working.

With the last UID now in the registry, the dialog can simply say what the reader
it listens to last read, and offer it. Paired to one reader, that reader answers
or nothing does. Listening to all of them, the most recently seen one wins,
which is the one the person most likely just used. The offer disappears once the
field already holds that UID, so it never sits there as a no-op.

Nothing changes for the tap: it still fills the field the moment it arrives.
2026-08-26 07:34:17 +02:00
Niko11111 4c2febbba6 feat(tags): remember the last UID each reader reported
The Add tag dialog waits for a fresh tap. That is fine when the tag is a
sticker in your hand, and awkward when the reader is a scale: the spool is
sitting on the pad to be weighed, and filling in the field means lifting it
and putting it back. A reader also cannot help here, because it has no reason
to report a tag that has not moved.

The registry already tracks each reader by id, name and last_seen, all in
memory. Keeping the last UID beside them is enough for a client to offer what
is on the reader right now, with no back channel to the device, no protocol
change, and nothing to update on the agent side - every existing ESPHome
reader gets this for free.

One UID, not a history: this answers "what is on the reader", not "what has
been". It lives and dies with the registry entry, so it is gone on restart
like the rest of it, and no scan is written anywhere.
2026-08-26 07:34:17 +02:00
github-actions[bot] e37045dcd4 Merge pull request #1119 from Donkie/weblate
Translations update
2026-08-25 21:07:10 +00:00
Micha f83b9d9ea4 Translated using Weblate (German)
Currently translated at 97.9% (287 of 293 strings)

Co-authored-by: Micha <hoagman@users.noreply.hosted.weblate.org>
Translate-URL: https://hosted.weblate.org/projects/spoolman/web-client/de/
Translation: Spoolman/Web Client LEGACY
2026-08-25 23:00:17 +02:00
github-actions[bot] 0b3d7ba140 Merge pull request #1118 from Donkie/weblatev2
Translations update from Hosted Weblate
2026-08-25 21:00:03 +00:00
Micha b6217c4b30 Translated using Weblate (German)
Currently translated at 93.9% (562 of 598 strings)

Translation: Spoolman/Spoolman Web UI v2
Translate-URL: https://hosted.weblate.org/projects/spoolman/spoolman-web-ui-v2/de/
2026-08-25 22:55:33 +02:00
Donkie 09953643dc Merge pull request #1116 from Donkie/fix-1115-scan-debounce-match
Key the tag scan debounce on the resolved match
2026-08-25 19:53:03 +02:00
Donkie a6512da598 Key the tag scan debounce on the resolved match
The relay debounced on (uid, reader_id) and time alone, so a scan whose match
had changed looked like a duplicate of one that resolved to nothing. An agent
that taps an unlinked tag, links it in its own UI, then re-reports the scan had
its correction swallowed for the whole 3 s window, leaving every subscriber that
trusts the broadcast still showing an unknown tag.

The key now includes matched_spool_id, so a repeat is only a repeat while the
scan still resolves to the same thing. Repeats of a still-unlinked tag keep
collapsing on (uid, reader, None), which is the reason the debounce exists.
should_broadcast takes the match as a required argument rather than an optional
one so a future call site cannot quietly drop it again.

Fixes #1115
2026-08-25 17:23:50 +02:00
Donkie 6da0902c8e Merge pull request #1113 from itCarl/fix/dashboard-spool-initial-weight
fix: dashboard total weight displayes filament weight instead of actual spool weight
2026-08-25 16:33:29 +02:00
github-actions[bot] 6bcda3d307 Merge pull request #1114 from Donkie/weblatev2
Translations update from Hosted Weblate
2026-08-24 18:11:23 +00:00
Micha 9dd0f73be1 Translated using Weblate (German)
Currently translated at 83.7% (501 of 598 strings)

Translation: Spoolman/Spoolman Web UI v2
Translate-URL: https://hosted.weblate.org/projects/spoolman/spoolman-web-ui-v2/de/
2026-08-24 20:06:20 +02:00
Maximilian Mewes 5171330c44 fix: dashboard total weight displayes filament weight instead of spool weight 2026-08-24 09:56:10 +02:00
Donkie 009f9e3bae Merge pull request #1111 from Donkie/github-sponsors-button
Replace Ko-fi buttons with GitHub Sponsors
2026-08-23 18:09:36 +02:00
Donkie a039095360 Replace Ko-fi buttons with GitHub Sponsors
Both frontends and the README now point at github.com/sponsors/Donkie.

The GitHub-suggested iframe embed is not usable here: Spoolman is often
run on a LAN with no internet access, so it would render as an empty box,
and it cannot be translated or themed. The existing buttons keep their
shell and get an inlined Octicon heart plus a translated label instead.

Only the en locale source is touched; the new "sponsor" key goes out to
the other locales via Weblate.
2026-08-23 17:38:31 +02:00
Donkie 205de5f0ce Update FUNDING.yml 2026-08-23 17:19:51 +02:00
Donkie 05a1b12e33 Merge pull request #1110 from Donkie/dependabot/npm_and_yarn/client/multi-e855e31deb
build(deps): bump brace-expansion in /client
2026-08-23 17:19:02 +02:00
dependabot[bot] f458995104 build(deps): bump brace-expansion in /client
Bumps  and [brace-expansion](https://github.com/juliangruber/brace-expansion). These dependencies needed to be updated together.

Updates `brace-expansion` from 2.1.1 to 2.1.4
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v2.1.1...v2.1.4)

Updates `brace-expansion` from 1.1.15 to 1.1.18
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v2.1.1...v2.1.4)

Updates `brace-expansion` from 5.0.7 to 5.0.9
- [Release notes](https://github.com/juliangruber/brace-expansion/releases)
- [Commits](https://github.com/juliangruber/brace-expansion/compare/v2.1.1...v2.1.4)

---
updated-dependencies:
- dependency-name: brace-expansion
  dependency-version: 2.1.4
  dependency-type: indirect
- dependency-name: brace-expansion
  dependency-version: 1.1.18
  dependency-type: indirect
- dependency-name: brace-expansion
  dependency-version: 5.0.9
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
2026-08-23 10:17:19 +00:00
Donkie 9f048a34c8 Merge pull request #1096 from Donkie/worktree-nfc-design-docs
Identify spools by NFC/RFID tags
2026-08-23 12:14:03 +02:00
Donkie ba891d5830 client_v2: let a scanned tag keep the view you were in
Auto-navigate rewrote the URL to a bare `/?sel=spool:N`, which since the filter
menu landed means a tap throws away the grouping, sort and filter chips you had
set up -- and lands on the shipped default view rather than the remembered one.

openSearchResult is the navigation a picked search result already gets, and a
tag scan asks the same question: on the Library it merges the selection into
the current view, elsewhere it opens the Library on just that spool. The
inspector resolves a selection by id on its own, so the spool still opens when
the active filters exclude it from the list behind it.
2026-08-23 10:07:02 +02:00
Donkie f841da6561 Point SpoolTag.from_db at the class the table actually has
d43552b renamed the ORM class from SpoolTag to Tag and missed this annotation.
It is evaluated when the class body runs, so importing spoolman.api.v1.models
raised AttributeError -- the server could not start and every test in the tree
failed to collect.
2026-08-23 10:07:02 +02:00
Donkie 931e3c9b3b Merge remote-tracking branch 'origin/master' into worktree-nfc-design-docs
Master split filter application in two: the filters a filament can answer on
its own (_apply_filament_filters) now serve both the spool query and the new
include_empty query, which selects FROM the filaments so that a filament with
no spools still produces a group.

The tag filter stays where it was, in _apply_spool_filters, and the comment
there now says why it cannot move: a tag is linked to a spool, so a filament
on its own can no more answer "which tag is on you" than it can answer "which
shelf are you on". Nothing routes a tag filter into the filament-driven query
-- it never calls this builder, and the group endpoint takes no `tag` -- so
there is no silently-dropped filter to guard against.
2026-08-23 10:06:30 +02:00
Donkie 9775c2c42e Merge pull request #1097 from Donkie/client-v2-issue-1080-rest
client_v2: sort direction, out-of-stock filaments and truncation tooltips
2026-08-23 09:04:47 +02:00
github-actions[bot] a9e50559bb Merge pull request #1109 from Donkie/weblatev2
Translations update from Hosted Weblate
2026-08-22 17:08:31 +00:00
Micha 91d5dc8f42 Translated using Weblate (German)
Currently translated at 70.9% (384 of 541 strings)

Translation: Spoolman/Spoolman Web UI v2
Translate-URL: https://hosted.weblate.org/projects/spoolman/spoolman-web-ui-v2/de/
2026-08-22 19:04:36 +02:00