Follow-up to #18960
The aforementioned PR fixed an issue in which switching notification filters
while notifications were loading prevented the query for the new filter from
running, but another issue remained: if the first query completed after the
second one, its results would override the second one, thus leading to the
same issue.
This commit cancels the first request if it is still running, before issuing
the second one.
* Add model for custom filter keywords
* Use CustomFilterKeyword internally
Does not change the API
* Fix /filters/edit and /filters/new
* Add migration tests
* Remove whole_word column from custom_filters (covered by custom_filter_keywords)
* Redesign /filters
Instead of a list, present a card that displays more information and handles
multiple keywords per filter.
* Redesign /filters/new and /filters/edit to add and remove keywords
This adds a new gem dependency: cocoon, as well as a npm dependency:
cocoon-js-vanilla. Those are used to easily populate and remove form fields
from the user interface when manipulating multiple keyword filters at once.
* Add /api/v2/filters to edit filter with multiple keywords
Entities:
- `Filter`: `id`, `title`, `filter_action` (either `hide` or `warn`), `context`
`keywords`
- `FilterKeyword`: `id`, `keyword`, `whole_word`
API endpoits:
- `GET /api/v2/filters` to list filters (including keywords)
- `POST /api/v2/filters` to create a new filter
`keywords_attributes` can also be passed to create keywords in one request
- `GET /api/v2/filters/:id` to read a particular filter
- `PUT /api/v2/filters/:id` to update a new filter
`keywords_attributes` can also be passed to edit, delete or add keywords in
one request
- `DELETE /api/v2/filters/:id` to delete a particular filter
- `GET /api/v2/filters/:id/keywords` to list keywords for a filter
- `POST /api/v2/filters/:filter_id/keywords/:id` to add a new keyword to a
filter
- `GET /api/v2/filter_keywords/:id` to read a particular keyword
- `PUT /api/v2/filter_keywords/:id` to edit a particular keyword
- `DELETE /api/v2/filter_keywords/:id` to delete a particular keyword
* Change from `irreversible` boolean to `action` enum
* Remove irrelevent `irreversible_must_be_within_context` check
* Fix /filters/new and /filters/edit with update for filter_action
* Fix Rubocop/Codeclimate complaining about task names
* Refactor FeedManager#phrase_filtered?
This moves regexp building and filter caching to the `CustomFilter` class.
This does not change the functional behavior yet, but this changes how the
cache is built, doing per-custom_filter regexps so that filters can be matched
independently, while still offering caching.
* Perform server-side filtering and output result in REST API
* Fix numerous filters_changed events being sent when editing multiple keywords at once
* Add some tests
* Use the new API in the WebUI
- use client-side logic for filters we have fetched rules for.
This is so that filter changes can be retroactively applied without
reloading the UI.
- use server-side logic for filters we haven't fetched rules for yet
(e.g. network error, or initial timeline loading)
* Minor optimizations and refactoring
* Perform server-side filtering on the streaming server
* Change the wording of filter action labels
* Fix issues pointed out by linter
* Change design of “Show anyway” link in accordence to review comments
* Drop “irreversible” filtering behavior
* Move /api/v2/filter_keywords to /api/v1/filters/keywords
* Rename `filter_results` attribute to `filtered`
* Rename REST::LegacyFilterSerializer to REST::V1::FilterSerializer
* Fix systemChannelId value in streaming server
* Simplify code by removing client-side filtering code
The simplifcation comes at a cost though: filters aren't retroactively
applied anymore.
Fixes#18309
The quickFilter logic was used on display and to request new notification
pages, but not for live updates. The main issue this caused is bump the unread
notifications count regardless of the quickFilter setting.
Since notifications are re-fetched when changing quickFilter settings, it is
safe to drop live notifications that do not match the selected filter.
* Add notifications when a reblogged status has been updated
* Change wording to say "edit" instead of "update" and add missing controls
* Replace previous update notifications with the most up-to-date one
* Change notification permission handling
- allow changing individual alert settings even if permission is not explicitly
enabled (asks for permission on toggle)
- persist permission request banner dismissal across sessions through settings
* Add additional, more discrete message to grant permissions
* Change permission granting button design according to reviews
Co-authored-by: Claire <claire.github-309c@sitedethib.com>
* Add notification permission handling code
* Request notification permission when enabling any notification setting
* Add badge to notification settings when permissions insufficient
* Disable alerts by default, requesting permission and enable them on onboarding
* Add bell button
Fix#4890
* Remove duplicate type from post-deployment migration
* Fix legacy class type mappings
* Improve query performance with better index
* Fix validation
* Remove redundant index from notifications
* Periodically save timeline markers
This saves timeline markers immediately upon message arrival, but not more
than once every 5 minutes.
This does not change how the markers are saved on closing the window,
except that it avoids submitting them if there is no need for it.
* Use the Fetch API when possible instead of XHR on window unload
* Add announcements
Fix#11006
* Add reactions to announcements
* Add admin UI for announcements
* Add unit tests
* Fix issues
- Add `with_dismissed` param to announcements API
- Fix end date not being formatted when time range is given
- Fix announcement delete causing reactions to send streaming updates
- Fix announcements container growing too wide and mascot too small
- Fix `all_day` being settable when no time range is given
- Change text "Update" to "Announcement"
* Fix scheduler unpublishing announcements before they are due
* Fix filter params not being passed to announcements filter
* Add follow_request notification type
The notification type already existed in the backend but was never pushed
to the front-end. This also means translation strings were also available
for the backend, from the notification mailer.
Unlike other notification types, these are off by default, to match what
I remember of Gargron's view on the topic: that follow requests should not
clutter notifications and should instead be reviewed at the user's own
leisure in the dedicated column.
Since follow requests have their own column, I've deemed it unnecessary to
add a specific tab for them in the notification quick filter.
* Show follow request link in single-column if there are pending requests, even if account isn't locked
* Push follow requests from notifications to the follow_requests list
* Offer to accept or reject follow request from the notification
* Redesign follow request notification
* Optimize makeGetStatus
Because `ImmutableList.filter` always returns a new object and `createSelector`
memoizes based on object identity, the selector returned by `makeGetStatus`
would *always* execute.
To avoid that, we wrap `getFilters` into a new memoizer that memoizes based on
deep equality, thus returning the same object as long as the filters haven't
changed, allowing the memoization of `makeGetStatus` to work.
Furthermore, we memoize the compiled regexs instead of recomputing them each
time the selector is called.
* Fix memoized result being cleared too often
* Make notifications use memoized getFiltersRegex
The active filter is stored in the web app's settings, but no save
is explicitly triggered, meaning that it is only saved when a different
setting is changed.
* Process incoming poll tallies update
* Send Update on poll vote
* Do not send Updates for a poll more often than once every 3 minutes
* Include voters in people to notify of results update
* Schedule closing poll worker on poll creation
* Add new notification type for ending polls
* Add front-end support for ended poll notifications
* Fix UpdatePollSerializer
* Fix Updates not being triggered by local votes
* Fix tests failure
* Fix web push notifications for closing polls
* Minor cleanup
* Notify voters of both remote and local polls when those close
* Fix delivery of poll updates to mentioned accounts and voters
* create FilterBar componer and its container, unstyled
* introduce basic styling for FilterBar
* add selection css
* allow FilterBar to display active CSS with js
* connect the FilterBar to the Redux state
* change getNotifications to use filter
* remove temporary comments
* add an option to turn the FilterBar off in settings
* fix showFilterBar data type to boolean
* fix eslint errors
* add English and Polish translations
* allowed filter bar overflow to accomodate for longer languages
* fix mispelled translation key
* add unified CSS look
* replace text in FilterBar with icons
* add tooltips
* replace text @ with an icon
* introduce simple and advanced filtering view
* add ability to toggle the advanced view
* add Polish translations
* change Advanced View description to be more clear
* make each filter flush notifications and load new ones, fixing pagination
* simplify getNotifications once frontend filtering is not needed for FilterBar
* add a semicolon
* Revert "simplify getNotifications once frontend filtering is not needed for FilterBar"
This reverts commit 9f4be7857135b0327814bd22a3e8a4e7b546f7cc.
* reset filter to 'all' when turning off FilterBar
* Use global loading indicator when loading more items
* Use local loading indicator for notifications
And remove global loading indicator for initial custom emojis load
> Good lord what is happening in there
Previously the contents of the Web Push API payloads closely resembled the structure of JavaScript's [Notification](https://developer.mozilla.org/en-US/docs/Web/API/Notification). But now that the API is open to non-browser apps, and given that there is no required coupling between contents of the payload and a Notification object, here is how I changed the payload:
```json
{
"access_token": "...",
"preferred_locale": "en",
"notification_id": "12345",
"notification_type": "follow",
"title": "So and so followed you",
"body": "This is my bio",
"icon": "https://example.com/avatar.png"
}
```
The title, body and icon attributes are included as a fallback so you can construct a minimal notification if you cannot perform a network request to the API to get more data.