Commit Graph

6471 Commits

Author SHA1 Message Date
Andy Smith 25adfbbcb0 Merge pull request #2584 from basecamp/settings-overflow-fix
Make generic scrollable list class for settings
2026-02-20 11:47:31 -06:00
Rosa Gutierrez 3e5233239b Fix push notification not firing on notification creation
- Rails only applies the last callback when `after_create_commit` and
  `after_update_commit` reference the same method name [1]:

> However, if you use the `after_create_commit` and the
`after_update_commit` callback with the same method name, it will only
allow the last callback defined to take effect, as they both internally
alias to `after_commit` which overrides previously defined callbacks
with the same method name.

- Push notifications were never sent when a notification was first
  created — only when the source was updated
- Replaced the two callbacks with a single `after_save_commit`, which
  fires on both create and update, with the
  `source_id_previously_changed?` guard (true for both new records and
  source changes)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>

[1] https://guides.rubyonrails.org/active_record_callbacks.html#aliases-for-after-commit
2026-02-20 18:37:33 +01:00
Andy Smith 17d869cf08 Cleanup unused classes 2026-02-20 11:09:15 -06:00
Andy Smith f835c211af Make generic scrollable list class for settings 2026-02-20 11:05:26 -06:00
Rosa Gutierrez bb6f2963b4 Revert commits accidentally pushed to main
Revert "Add bridged share button to board and card permas"
This reverts commit 069e165b43.

Revert "Move helper to bridge helper file"
This reverts commit 1ee37f046c.
2026-02-20 12:58:39 +01:00
Adrien Maston 069e165b43 Add bridged share button to board and card permas 2026-02-20 12:49:00 +01:00
Adrien Maston 1ee37f046c Move helper to bridge helper file 2026-02-20 12:46:00 +01:00
Adrien Maston 92a845b17b Remove additional space above header
... to align with native titles
2026-02-19 17:54:02 +01:00
Adrien Maston 0394c44f22 Merge pull request #2577 from basecamp/fix-unpin-typo
Fix "Unpin" typo
2026-02-19 16:53:29 +01:00
Adrien Maston 904917f648 Up-pin should be Unpin 2026-02-19 16:36:32 +01:00
Zoltan Hosszu b248183b54 Fixed extra padding in mentions dropdown 2026-02-19 16:25:52 +01:00
Zoltan Hosszu 9c01434f68 Fixed missing attachment selection outline 2026-02-19 16:25:41 +01:00
Adrien Maston c2d5070840 Merge pull request #2567 from basecamp/mobile/fix-empty-search 2026-02-19 14:28:54 +01:00
Adrien Maston 5f25ebe3f4 Add a line break, it looks better 2026-02-19 14:25:26 +01:00
Adrien Maston f2fb05cecf Replace unless by if 2026-02-19 14:09:48 +01:00
Adrien Maston 97f2f677d6 Don't render empty state instead of hiding it 2026-02-19 14:04:14 +01:00
Adrien Maston 0e1feb0f3f Create @query in controller instead of testing for blank? 2026-02-19 12:06:49 +01:00
Jeremy Daer 953942694f Handle MissingEOCD as invalid zip file, not job failure (#2572)
ZipKit::FileReader raises MissingEOCD for truncated, corrupted, or
non-zip files. This exception is a direct StandardError subclass, not
a subclass of InvalidStructure or ReadError, so it escaped as an
unhandled job failure instead of being caught and surfaced to the user.

Broaden the rescue in ZipFile::Reader#initialize to catch ReadError
(parent of InvalidStructure), MissingEOCD, and UnsupportedFeature.
2026-02-18 15:18:56 -08:00
Mike Dalessio 41675224d0 Remove redundant insecure context CSRF check
Rails now handles the insecure context case natively in
verified_via_header_only? — when Sec-Fetch-Site is missing and the
request is plain HTTP without force_ssl, the request is allowed.

Remove the now-redundant allowed_insecure_context_request? method and
update the test to set ActionDispatch::Http::URL.secure_protocol
alongside Rails.configuration.force_ssl so the upstream check works
correctly in the test environment.
2026-02-18 14:06:46 -05:00
Adrien Maston 5c0508d91c Don't show "no match" when not searching anything yet 2026-02-18 18:19:37 +01:00
Alp Keser 056dfc1367 Merge pull request #2528 from basecamp/mobile/missing-boards-fix
Update boards JSON to return all accessible boards ordered by recently accessed
2026-02-18 13:20:49 +03:00
Alp Keser 610cf7a190 Merge pull request #2398 from basecamp/notifications-tray-api
Add JSON response support for `notifications/tray`
2026-02-18 13:19:59 +03:00
Kevin McConnell 4e9773f9f5 Correct card URL in comment JSON output
When rendering details of a comment, we were using the card's `id` as
the param for the URL. But card routes use the card's number, not ID.
2026-02-17 17:11:39 +00:00
Stanko Krtalić 4b2586769b Merge pull request #2556 from basecamp/fix-notifications-staying-unread-on-card-visit
Reinstate card readings
2026-02-17 14:15:24 +01:00
Stanko K.R. 9d4db14fc3 Reinstate card readings 2026-02-17 13:57:24 +01:00
Alp Keser 13d7cd4303 Paginate boards JSON 2026-02-17 10:37:23 +03:00
Jeremy Daer a253c31dee Batch webhook delivery cleanup to prevent DB lock contention (#2555)
Follow-up to #2550 which added a created_at index and increased cleanup
frequency. The delete itself was still unbatched and vulnerable whenever
a backlog accumulates (first run after deploy, clock skew, etc).

Delete in small batches with a pause between each to let other
transactions through, following the SolidQueue pattern.
2026-02-16 15:31:10 -08:00
Adrien Maston a1e96670ce Merge pull request #2524 from basecamp/mobile/fix-card-perma-footer
Mobile / Fix card perma footer
2026-02-16 17:39:22 +01:00
Adrien Maston 910500eaf6 Merge pull request #2520 from basecamp/mobile/fix-truncated-card-header
Mobile / Fix truncated card header
2026-02-16 17:38:36 +01:00
Andy Smith eee93cb17d Merge pull request #2553 from basecamp/apostrophe-fix
Use the correct apostrophe character
2026-02-16 10:12:50 -06:00
Andy Smith c41e5aa981 Merge pull request #2437 from nqst/dialog-ux-improvements
Modal dialogs: smoother animations and QR code dialog improvements
2026-02-16 10:12:30 -06:00
Andy Smith 26c380448b Use the correct apostrophe character 2026-02-16 10:03:53 -06:00
Andy Smith edb2f91bbb Merge pull request #2451 from nqst/fix-safari-glitches
Fix Safari transition glitches
2026-02-16 09:58:26 -06:00
Andy Smith b638998789 Merge pull request #2456 from nqst/qr-code-in-dark-mode
Improve QR code appearance in dark mode
2026-02-16 09:54:54 -06:00
Rosa Gutierrez 95114b1d67 Fix race condition between concurrent Event and Mention notifier jobs
When concurrent NotifyRecipientsJobs process an Event and a Mention for
the same user+card, Rails' dirty tracking can skip writing source_type
in the UPDATE if it hasn't changed from the stale in-memory value,
leaving source_type and source_id mismatched (e.g. source_type='Event'
with a Mention's source_id, resulting in a nil source).

Force source_type to always be included in the UPDATE via
source_type_will_change! to prevent this.

Here's a sample timeline of this race condition happening in the real
world (with simplified IDs):

Two `NotifyRecipientsJob` involving notification `03fklpu`, same card,
same user, same comment — enqueued within 50ms of each other:

1. Both jobs load notification `03fklpu` — it has source_type='Mention'
   (from a previous job)
2. `EventNotifier` writes at 21:22:36.051: ```sql SET
   source_type='Event', source_id=<event_id>, unread_count=1 ```
3. `source_type` included because it changed ('Mention' → 'Event')
4. `MentionNotifier` writes at 21:22:36.057 (~6ms later): ```sql SET
   source_id=<mention_id>, unread_count=1 ```
5. No `source_type`! It was `'Mention'` when loaded and `'Mention'` is
   what it's setting → not dirty → skipped
6. Final DB state: `source_type='Event'` (from step 2, untouched),
   `source_id=<mention_id>` (from step 3)

`Notification.source` now does `Event.find(<mention_id>) → nil.`

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 16:50:46 +01:00
Andy Smith bee16f5f9c Merge pull request #2548 from nqst/fix-notifications-typography
Push notification section typography fixes
2026-02-16 09:45:42 -06:00
Andy Smith d31756fed3 Merge pull request #2549 from basecamp/fix-typo
Fix typo
2026-02-16 09:41:03 -06:00
Alp Keser a48c88cb5d Stabilize notifications tray test ordering via fixture updated_at timestamps 2026-02-16 18:33:32 +03:00
Alp Keser bcc0f93bb9 Preload notification card associations used by JSON responses 2026-02-16 17:58:33 +03:00
Rosa Gutierrez b742963f7c Add account ownership check to import GID resolution
The convert_gids_to_sgids method resolved GIDs globally and minted
valid SGIDs without verifying the record belongs to the importing
account. This adds the same account_id check that the export path
already has, plus RecordNotFound handling for invalid GIDs.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-16 11:49:00 +01:00
Andy Smith 1572e70b65 Fix typo 2026-02-13 17:45:58 -06:00
Andy Smith f2bf7c7460 Merge pull request #2547 from basecamp/import-export-clarification
Import export clarification
2026-02-13 17:40:35 -06:00
Alexander Zaytsev bef5bb60c9 Target correct selector 2026-02-14 00:17:16 +01:00
Alexander Zaytsev 635ef4fbe5 Fix paragraph rendering as an inline element 2026-02-14 00:02:56 +01:00
Andy Smith d7814792e3 Tweak language 2026-02-13 15:17:33 -06:00
Alexander Zaytsev 6f839c5b2f Remove periods after ellipses 2026-02-13 18:21:47 +01:00
Alexander Zaytsev da5e67a0a6 Use h3 instead of h2 2026-02-13 18:19:38 +01:00
Adrien Maston e3edb98465 Merge branch 'main' into mobile/fix-card-perma-footer
* main: (33 commits)
  Revert "Add temporary performance degradation message"
  Fix double-escaped HTML entities in webhook payloads
  Fix crash when a notification is deleted while a bundle is being sent
  Fix race condition on notification creation
  Fix double _seconds suffix in GVL request wait metric name (#2539)
  Add GVL contention metrics via gvltools (#2538)
  Backfill tests for Event::Description strings' html-safety
  Update copy
  Add temporary performance degradation message
  Render inline code in card titles (#2518)
  Add stackprof for profiling
  Table style tweaks
  Fix dark mode colors
  Index notifications on updated_at
  Stack notifications everywhere
  HR fixes
  Removing duplicate code language picker
  Regression fixes
  Touch up link button hover styles
  Remove link dialog size limit
  ...
2026-02-13 15:44:01 +01:00
Mike Dalessio dc492ef17e Merge pull request #2540 from basecamp/fix-quotes
Fix double-escaped HTML entities in basecamp and campfire webhook payloads
2026-02-13 09:26:00 -05:00
Adrien Maston 6bacbdce78 Fix trailing margin depending on boosts 2026-02-13 12:17:36 +01:00