When the base of a bundle cannot be rendered
(canRender() returns false), the bundled items still
have to be rendered and potentially marked-as-read as well.
If we don't do this, the base is filtered out, marked as read,
the counter goes down by 1 and the bundled notifications are ignored.
On the next query a new base is selected, filtered out, etc.
So if a bundle of 10 notifications cannot be rendered because it's
10 new topics on a deleted flow board, the flyout has to be opened
10 times for the counter to finally be 0.
Change-Id: I06962b25e36802ef00278e2bc70d5377b5874695
When requesting notifications, the 'continue' value used
for pagination is only included if there is more
notifications than requested. When some are filtered out,
there is less notifications and no 'continue' value,
which leads to no pagination at all on the special page.
Change-Id: I1a13d2a343f4e60489e2a6a0474c97664ed00d46
Like count, it is available both grouped by section and ungrouped
(top-level).
Unlike count, the top-level still has both sections (but with the
string 'seenTime' at the root), and if groupbysection is used,
it will not also have top-level (since it would be redundant).
Example output at T139993
It will be false or omitted if there is no seen time, depending
on JSON format version (2+ is false).
Bug: T139993
Change-Id: I9f4f9df69203204b56002afa1be6ed2336c33898
When trying to find the max timestamp of all
notifications in one source or the max timestamp
between all the sources, check for empty array
to avoid "Warning: max(): Array must contain at
least one element...".
Bug: T139529
Change-Id: I0bf04ded40872c1c7a0cd3a9a62bc789814f5419
This should prevent fatals in the sort-by-timestamp code
farther down, and also prevent incorrect output.
Bug: T139112
Change-Id: I6480b2e751594ba3392322f40e950f95ae702104
Use foreign source reported notifications count
instead of counting the actual objects.
Counting objects is wrong because of bundles
that are 1 object but represent multiple notifications.
Bug: T138888
Change-Id: Ib63efc1e33af8f4364a7ba11a0dc3ff820f0a03c
To allow individual notifications to be
marked as read/unread or moderated,
bundles are created by grouping associated
notifications when they are fetched for display
instead of when they are created.
From a product perspective, this change doesn't
introduce moderation or expandable bundles but
it counts each individual notifications.
For instance, the bundled notification
"3 new topics on PageA" now counts as 3
notifications.
Bug: T93673
Bug: T120153
Change-Id: Iacd098573efd92bb1e3fcd7da4cd40cea9522f15
Uses the magic value '[]' to mean 'no title'. This is a bit ugly,
but I think introducing an additional ¬withouttitle=1 parameter
is uglier and results in more code.
Change-Id: I83278182aeaf3905eb0f3e24c4c6c247720b1e76
Adds $wgEchoSectionTransition and $wgEchoBundleTransition.
If either of these settings is enabled, we will disbelieve
the alert/message counts in the euw table and obtain them
using server-side cross-wiki API queries instead.
This affects both ApiEchoNotifications (for generating the cross-wiki
summary entry) and the count and timestamp computation in NotifUser.
In bundle transition mode, we trust that notifications are classified
correctly between alerts and messages, but we don't trust the
counts in the table. In section transition mode, we trust that
the sum of the alert and message counts is the correct count,
but we don't trust the alert and message counts individually.
If both modes are enabled, we mistrust anything that's mistrusted
by either mode and only trust what's trusted by both modes.
In any event, we do trust that only the wikis with rows in the
euw table have unread notifications.
Bug: T132954
Change-Id: Ibcc8ac102dac3cf06916d67427b42457fdb93db6
The query shouldn't be too expensive: it'll use an index to narrow
down the resultset for 1 user. After that, it'll be sorted based on
a grouped by value, but that should fit in memory: it'll never be
on more than 2000 entries, which is the max amount of notifications
per user.
Change-Id: I271ea7f7a6e010284739bfce02c4ec8a077148fc
CA tokens are single-use, and the fact that they even worked
for multiple requests was a race condition. Instead of getting
one CA token and using it for all requests, get a fresh token
for each request.
Bug: T135250
Change-Id: Ie1bbdefd3e265d009d0c42ff27da447b8da7f1fd
This is needed because global tables and cache keys will attempt to be used
even for users who don't have the preference enabled.
Bug: T135266
Change-Id: I6208a12d46c8cd0275a232663cd50ac2bd2fed1c
If all server-side cross-wiki requests fail, we'd return an empty API response.
This is invalid, the frontend expects things like list:[] to still be there.
Change-Id: I72fc5a017647ca28abbc061992fa4868ca5737f4
If we don't initialize $results, getForeignNotifications() will return
null, and this will cause a fatal when trying to += it into an array.
Change-Id: Ibb868cbf0b52ff2de41c5be82c9605801e51ffae
Passing a param 'wiki' with a list of wiki names will now
result in getting notifications from these wikis too.
It'll execute multi-curl calls to the given wikis to fetch
their results.
Bug: T130636
Change-Id: I89df54366501acfe3e5cf6d2f313ee32694ba387
Previously, getNotificationCount() only looked at local notifications,
and foreign notifications were added in separately by getMessageCount()
and getAlertCount(). This didn't make any sense and resulted in
counter-intuitive things like I4d49b543.
Instead, add a $global flag to getNotificationCount(). If $global=false,
the local count is returned as before, but if $global=true, the
global count (=local+foreign) is returned. If $global is omitted,
the user's cross-wiki notification preference determines which is returned.
Update getLastUnreadNotificationCount() in the same way, since it had
the same issues.
Also add caching for global counts and timestamps, using a global
memc key.
Bug: T133623
Change-Id: If78bfc710acd91a075771b565cc99f4c302a104d
Removing the info popup because we don't have to show
a privacy notice when linking within the wiki.
This adds a database query to every page view for logged-in
users; If78bfc710, once merged, will fix that.
Bug: T117669
Change-Id: I8451db34ae8e94264e4921ecd6df6e4b32c7623a
It doesn't use $this, except to call getWikiTitle(), so make that
static too. This allows us to use it in EchoForeignPresentationModel
without creating a second instance there.
Change-Id: If778db0852de1cbf5c2190ce50ce561745bb3887
I thought the name was confusing, and would be even more so
if we get real notifications from other sources.
Meanwhile also split $crossWikiSummary into 2 properties:
- 1 with the class
- 1 to indicate if it should be used
Change-Id: I0e83be7924c8c77680ea1ada3f2bd6a190ce6149
This would soon become problematic when output can come from
multiple sources, with potentially conflicting ids.
The ID is already included in the result anyway.
Change-Id: Id92150c71c68958819fe0ee329e70393052c34c9
It's (mostly) unused, and it would become problematic once we have
notifications from multiple places (where those ids could conflict)
Change-Id: Ib3bb5ae1e5689037b38290c9ce3d8691f52582b0
This caused notifications on mobile to show notifications for
both alert|message, as the type was always "all".
Bug: T130801
Change-Id: Ice245eb407ca360d8e882c0ba48cb7b3e0ecb851
Both in the order of the cross-wiki bundles themselves, and
in the message in the notification body.
ForeignNotifications tracks timestamps per wiki per section,
and exposes these through getWikiTimestamp(). ApiEchoNotifications
adds these timestamps to the sources manifest, and also sorts
the list of wikis by timestamp (it'd be nicer to do this in
ForeignPresentationModel instead, but then we'd have to create a new
ForeignNotifications instance which causes a duplicated DB query).
NotificationsModel receives the timestamp for its wiki as its
fallback timestamp, and makes getTimestamp() return this value
during the pre-population phase. This causes its parent to
automatically sort it correctly.
Because the timestamp of a wiki depends on the section (alerts vs messages),
we can't put it in the global sources manifest at the top level
of the API response. Instead, get rid of this global sources
manifest and put all the sources data in the foreign notifications
directly. This allows us to specify different timestamps, and also
allows us to get rid of code in EchoApi that was already remapping
the API response to this format.
Bug: T130298
Change-Id: Ie083fbb1ccaf74fbe804633d87ef03c9e71b120f
It's terrible that in groupbysection mode, you still have to pass
messageunreadfirst and alertunreadfirst separately, but at least
this way the unreadfirst feature is available at all in the
non-grouped mode.
Change-Id: Ifb0707be484bda8e33810c888bae1d008cac2d9f
API requests with notgroupbysection disabled but notsection set
to 'alert' would return foreign notification bundles for both
alerts and messages, separately.
The frontend always pasess notgroupbysection=1 in practice because
notmessageunreadfirst=1 doesn't work without it; but regardless of
that, the API module shouldn't return a foreign notification bundle
for messages when only alerts are requested.
Change-Id: I9fa6d1411a8c121591ce6dd75ee8052bcdcb478b