text-wrap: balance conflicts with -webkit-line-clamp in Safari, causing
titles to collapse into fewer lines and truncate early. Unset text-wrap
when the title is line-clamped on the board view.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
* main: (56 commits)
Update app/views/cards/container/_closure_buttons.html.erb
Update app/views/columns/show/_add_card_button.html.erb
Update app/views/events/index/_add_card_button.html.erb
Just return the object
Rename is-main-action to display-as-primary-action
Remove debug line
Rename show-label to display-title
Include path in web push payload for backwards compatibility
Add base_url to native push notification payload
Use internal account ID as `account_id` and add `account_slug`
Make APNS and FCM env vars available
Fix devices_path route helper in native devices partial
Fix tests for renamed fixtures and new stacked notifications
Add creator_familiar_name to push notification payload
Add creator initials and avatar color to push notification payload
Add avatar_url so we always get an avatar even when the user hasn't set one
Document --push flag for testing native push notifications
Don't read APNS_TEAM_ID from 1Password
Simplify push.yml to only use B64 encryption keys
Rename apns-dev to push-dev and unify 1Password credentials
...
Include the server's base URL so native apps can identify which Fizzy
instance (SaaS or self-hosted) a notification originated from.
Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Clear assignee's existing notifications in setup since Notifier now
uses create_or_find_by instead of create, and reload the association
to avoid caching after destroy_all.
Update fixture references after rebase: use `logo_assignment_kevin`
as base notification and `logo_mentioned_david` for mention tests.
Update source to `logo_published` in tests that need generic card events.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Move avatar_background_color logic from helper to User::Avatar concern
so it can be accessed from models. Include creator_id, creator_initials,
and creator_avatar_color in native push notifications for local avatar
rendering on iOS.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
In-flight jobs queued before deploy would fail if the old class is
missing. This shim delegates to the new notification.push method.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
The web push payload sends the URL in data.url but the service
worker was looking for data.path, resulting in undefined URLs.
Also fix WebPush::Notification test to use url instead of path
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Each target now implements process directly with its own logic,
rather than using processable?/perform_push hooks. The pushable?
check is done once in Notification#push before iterating targets.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
"Push to target" reads naturally - we push the notification to the
target. "Target processes" also makes sense - the target receives
and handles the notification in its own way.
- Add class method PushTarget.process(notification) that instantiates
and calls the instance method
- Rename instance method from push to process
- Add private push_to helper in Pushable for readable iteration
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace separate WebPushJob and NativePushJob with a single PushJob
that calls notification.push, which iterates over registered targets.
Each target handles its own delivery - Web pushes synchronously via
the pool, Native enqueues device-level jobs via deliver_later_to.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Use polymorphism instead of case statements in Native push target:
- DefaultPayload#category returns "default", #high_priority? returns false
- EventPayload#category returns "assignment"/"comment"/"card" based on action
- MentionPayload#category returns "mention", #high_priority? returns true
This simplifies the Native push target by delegating source-specific
logic to the appropriate payload classes.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
PushTarget#push reads more naturally than Push#push. The push target
is the thing that pushes notifications to a specific destination.
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>