Alert popup can now also have talk-page related notifications, so
we should make sure we listen to 'allTalkRead' event when it is
updating as well.
Bug: T141047
Change-Id: I1317efc63b503bd1a55734ebe377ff4c617fe485
And change all CSS and JS dependent calls/tags based on the new
tooltip message and ID of the personal tool <li> item.
Change-Id: I136fabe5710f90da10eb8d4afe92acdb77571eec
Add a global-wiki 'mark all as read' to the Special:Notifications page.
The 'mark all as read' will makr all notifications in the given
wiki. The context of the wiki changes when filters are chosen,
and so the message of the button changes as well.
Bug: T115528
Change-Id: Ibd9dcdf7072d6cbc1a268c18e558e6d0df28f929
As a first step for mobile support, make the page responsive,
hide the sidebar, and slightly adjust button/title positions and
sizes so they fit in a small screen.
Bug: T140687
Change-Id: I98f264948a57924f6370a861381456ce9c82f8d8
When there are only foreign notifications, marking them all
as read empties the flyout completely. With this change,
we now show the placeholder widget with the 'no notifications'
message instead.
Bug: T132202
Change-Id: I7ee38b160ca03c08711670a3296ba4ab45a5eb6c
We need a fixed-width CSS table with a number of fixed-width
cells and one cell that takes up the remaining width, with
text truncation. This is a pain to do with CSS tables,
but this trick I found on StackOverflow[1] works well:
wrap the contents of the cell in a div that's position: relative;,
containing another div that's position: absolute; width: 100%;
[1] http://stackoverflow.com/questions/7569436/css-constrain-a-table-with-long-cell-contents-to-page-width
Bug: T140349
Change-Id: I507f915f06185c767d7a5c8edbff6c341e07b6e2
When we are viewing a certain read state filter ('read' or 'unread')
the visibility of items should correspond to that state even when
the user marks a specific item as read/unread. That means that the
system should remove these items from view when the action is taken.
In this commit:
* The controller makes the judgment of whether to remove items when
read/unread action is taken, based on whether a filter is set.
* We clean up the terminology of discard - no more 'remove' - to
make sure we have consistency in the code.
* Related: The 'discard' event is now scoped within the hierarchy;
meaning, lists emit 'discard' when an item is removed, grouplist
emits 'discard' when a group is removed, and the manager emits
'discard' when an entire notification model is removed. This
means we can actually have proper hierarchy and organization with
a single event, and not worry about clashing between the intentional
'discard' action and the event 'remove' that is also used while
resorting happens.
* The model manager emits a discard event when a model is removed
so that the general list can listen to the manager and remove an
entire batch of items if needed.
* The pagination model now updates the count for the current page
rather than some vague notion of the last page. This is also
updated when the controller removes items, so we can get an
accurate count in the page for the number of notifications that
are displayed.
Bug: T136891
Change-Id: I247c618042ef256fadf09922f7b83bd1ad361f64
This organizes the operation of seenTime so we can store and
follow up on it based on different sources, as well as update
it correctly remotely when needed.
Change-Id: I629ecfc84999be998b45c9c7adb00ea7e3e51742
This would make the wiki names localized to the current user
interface language, rather than the wiki language.
Bug: T139807
Change-Id: I2b787e1486819d6833e169ac6db519cd36a3c3eb
The message for tooltip-pt-notifications-message was removed to comply
with the new naming. The problem is that in the back end, sections are
still defined as 'message' vs 'alerts' and the sections in the user
toolbar are defined with those terms. In no-JS mode (which is before
the user clicks any of the badges) this tooltip is created automatically
by MediaWiki based on class names.
It's easier to return the message key with different text for translation
and wait for the bigger tech debt to correct all instances of 'message'
to 'notice' (including in the API, which would require a much more
massive work)
Bug: T139520
Change-Id: I6368b63e38f64aa065f2580df812de1c63a93716
We need the API to return the notifications for the special page
in timestamp order and not read/unread order, so that the 'continue'
value is still correct.
On top of that, if we have many unread notifications, they should
still be placed according to the dates, so the API must bring back
proper result.
In this fix, we add 'unreadFirst' to filters, and only use that
filter when needed (namely, in the popup)
Bug: T136885
Change-Id: I3018d09b009d735402d83074a5ffcd14ea1c242a
When we fetch the pages per wiki, the API returns an object that
defines the local wiki we are in as its dbName; this then gets
stored into the model as the source, which forces us to check against
the dbName whenever we want to perform an operation so we can tell
the API layer to fetch and perform the actions locally, rather than
use a foreign API.
The term 'local' makes no sense for naming the model (and upcoming
tech debt work will fix this) but it makes sense in the context of
the API layer -- and hence, the source name should follow suit.
This fix makes sure that the local wiki objects always have their
sources defined to be 'local', and thus making us use the test for
dbName in very specific points (when we get the data) rather than
throughout the codebase, randonly.
This is also the first step to allow proper updating of things like
seenTime accross wikis, especially in cases where we view a remote
wiki as if it is local (in the Special:Notifications page)
Change-Id: I94633a1cd074580cbc5029d7c75d179e908e5c52
Instead of 'cheating' and externally aggregating the itemUpdate event
we should just let the relevant (non-xwiki) models aggregate this
centrally and properly, and include it as an offered event.
Change-Id: Ibe528fe971e1be8309a97275b1a1be8979306ff5
Following up on setting max-width, this actually should be strict
width for the moment (until we decide on more responsive design)
since without restricting width, the notification view becomes really
thin and compact if the list contains notifications that have short
titles and descriptions.
Bug: T138433
Change-Id: Ia663f7968033b01f3553a326f70736cc6a6a54a9
This is to make sure that concatenation of text inside items works
properly given CSS table-layout.
Bug: T138433
Change-Id: Iae32cbf82cdb91880c7ccd7df14d167eb75527cf
Marking local or xwiki notifications as read
are different operations that require different
information. Call different functions on the
controller.
Bug: T139114
Change-Id: I824ca668c31ab41d101c632442c91d3a8a1e5c5a
If there are more than 2 prioritized actions, put those actions
in the dotdotdot menu.
Also, correct the name of a variable from "isInsideMenu" to what
it actually represents, which is, in fact, "isOutsideMenu"
Bug: T126617
Bug: T125949
Change-Id: I95fcae8f822e51d9353599c09f1550797e4ad673
This rule ensures that long human-readable wiki names
don't cause horizontal scroll bars in the notifications
popup.
Change-Id: Id0c954d2059aeed875fa2eea7a45537aac4e2e58
The bounding box of where this cursor effect is applied isn't
quite the same as with bundled notifications (which in turn isn't
the same as with normal notifications), but to fix that we need
to normalize the DOM structures of the three types. They
currently differ in the presence/absence of the <a> wrapper
and in how padding and margins are used.
Bug: T138913
Change-Id: I1ed32e0a9deca62b68d08acd0699431ddda8ca44
If we are marking the item as read/unread, we don't want the change
in class to trigger the unseen animation. When that happens, first
remove the 'initiallyUnseen' class (that triggers the animation)
and only then mark the item as read or unread.
Bug: T138522
Change-Id: I05e02518feb1fc166297594053a084718dcb7194
Also add border-box to prevent the circle from appearing
to grow when a border appears.
Bug: T126214
Change-Id: Id5e89ff87759c4ae44851d5ad3061230a0e59ff0
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
This will allow us to let the user click filters quickly, effectively
changing the promises sent to the API, but let the API only resolve
with the latest requested promise.
Bug: T136895
Change-Id: I698a2b8eced6d8ee997efef353697d27d92cfb2f
Adding up numbers in the front-end is not enough, because it could
be that not all pages are listed (it's a top 10). So get the
total count from the backend.
Change-Id: Ibbc76691ef88333b92132a514fdba3cde3797e10
Add a sidebar with cross-wiki sources and pages of unread notifications.
The filter allows the user to fetch notifications from a foreign source
and specific pages if those exist.
Bug: T129366
Change-Id: I57d827a47f80274d75364c2099a9624049a26834
Allow for mark read and mark unread through the side button, and
change its style according to spec in the ticket.
Bug: T126214
Change-Id: I78a93c0545bbe2d7c11a0c62557cd2e97e9d3866
This ensures that the fallback timestamp is used if the list is
still empty. Not doing this causes the wikis in the cross-wiki bundle
to appear in the wrong order. Also, it makes more sense to use the
model as the source of truth regardless.
Bug: T138115
Change-Id: Icbfdc7e7c7f67179e50f0f692aef1a54568265e6
- Remove duplicated counter adjustments.
- Differentiate between all IDs to mark as
read vs. all IDs that represent visible
notifications when adjusting the counter.
Change-Id: I1b3e52a929c6e920e3b782c9ef028539b3db0c99
This is done the quick way by just turning
off a config option. The full cleanup
is in I095704252eaf2f8fe71950a4cfcd42a6fce431ff
Bug: T132525
Change-Id: I5becaa2f91b7eff6ebe4ce3943e86975c844c884
The "Mark all as read" button had margins that made it just a little
bit taller than the header would otherwise be. This pushed the
bottom border of the header and the top border of the first notification
away from each other.
We only need top and right margins on this button, so drop the
bottom and left margins.
Bug: T137778
Change-Id: I8d47d84c79cbdad707b8cbaa8d43187c054755b3
This should have been done from the beginning; the model manager
pulls models by their symbolic names. So far, we've used the source
for that, but that assumes that two modules always have different
sources, and that is absolutely not necessarily the case.
For example, internal local bundles will each be a model, but have
the same ('local') source. They should still be differentiated in
the manager by their names, but the source should state clearly that
it is local.
For this, the models now have "getName" method and the name is
created separately from their source. Items also preserve a
reference to their parent's symbolic name so they can provide
that for items that require the controller to manipulate a specific
model.
Change-Id: I8c39d5d28383d11fb330addce21e07d5c424da6f
In the current bundling system, only the
bundle base is mark as read. It leaves all
the non-base bundled notifications without
a read_timestamp. They would all appear
as read in the new bundling system.
With this change, all notifications in
a bundled are update with a read_timestamp
when the bundle is read.
The implementation of this change is
somewhat temporary as the new bundling
system brings changes to the models
and controller.
Bug: T136368
Change-Id: I70b71d722d8d62cbdd1adc004293030ef900ac94
The zero results can either be because there are no notifications
at all for this user in the local wiki, or because there are no
results for the specific filter. Both messages are used for either
case.
Also, clean up the display of push/pop pending for the inbox widget
and hide the label in case the message count is 0 or 1 notifications
as it is unhelpful and irrelevant in these cases.
Bug: T136586
Bug: T136574
Bug: T129363
Change-Id: I1465f772bb9f5247df645d6612f951e5fd7d38cf
Add a pagination widget with events and separate the logic for
organization. Let the widget listen to events from the pagination
model so it always keeps itself updated.
Change-Id: Id1df112cbb0d90195217e88fbee97a59170b99c5
The items should resemble the popup items, but the styles clashed
with the popup's cross-wiki notification item, so the image size
was smaller and the border was incomplete.
Bug: T136572
Change-Id: I3c3f825d469ccee1e711da21f627eeb9491e9480
Change the pending element to be the notifications list rather than
the whole inbox widget in the Special:Notifications page.
Bug: T136581
Change-Id: I82b073c9cd628f30c13305510d6604e3ef636c2a
Show an API failure message if the request failed.
Also take this opportunity to show a message in case
there are no notifications at all.
Bug: T136467
Change-Id: If5761ec3d3df10a8774561bed06a4ade54458c4b
We don't show an error message in this case, just an
empty popup, so that should be fixed regardless.
Bug: T136467
Change-Id: I06ddd5306bd8d7edeb8c75bdae7abd7215285e3d
There was quite a small link under the main title in Special:Notifications
which pointed to a related help page. Now the OutputPage::addHelpLink()
method is used which moves this link to the upper right corner and allows
configuring this on-wiki (instead of LocalSettings.php or so).
Bug: T101057
Change-Id: Ib4aecee8006b8d71bb3cd86f1d4ebdfee9080870
* Use `margin: A` with `padding: B` rather than `padding: calc(A + B)`.
* Remove a `display: inline-block` which necessitated `width: 100%`.
I think this results in the same rendering, but please test carefully,
as I didn't check it for all the possible notifications.
(There is one more calc() in mw.echo.badge.less that can't be avoided.)
Bug: T135936
Change-Id: Ic01f16c8469c3b9d45d2885108ec6260e967731a
Allow for the widget to have a mark-as-read button to its individual
groups, as well as change the event listening from 'remove' to 'discard'
The problem with 'remove' event is that it is triggered when an item
is either intentionally removed from the list *and* when an item is
changing its position in the list (move event includes 'remove' and
then 'add' event)
If we listen to 'remove' events we will get both cases, which is
unhelpful. Instead, a new event - 'discard' - was introduced so
we are certain it is used with the clear intention of removing the
item completely.
Change-Id: Ia08720bf4c547fa41edf62331eeb1a45ff4965b7
We have to make sure that any notifications wrapper has the css
term overflow-y: auto; so that the popup menus behave properly.
Change-Id: I14a1a9f1c3610ef27fe04aa4b1e7197c08d1dfd4
Changing the way Echo's front-end architecture works to work with
model-view-controller methodology.
Change-Id: I97862402c41bc04dd41cd08d79f19ff677340249
Also, get rid of the feature where we hide the project name when there
is only one project available. The titles are always showing.
Bug: T127419
Change-Id: I1b1285d84b7fb4775d13067e6ae1c50602ed3baf
Foreign notification sources can end up being empty
for legitimate reasons (already marked as read on the
foreign wiki) or errors (failed to query remote server).
This change makes the front-end resilient by
removing the sources if they end up being empty,
and removing the foreign notifications bundle if
all the sources end up being empty.
Bug: T135252
Bug: T135250
Change-Id: I5901bb0007420a19d8c0727faa982eb00809c074
Some complexity is now gone. We didn't currently have a good justification
for a the APIHandler factory: the apiHandler caller would have to specify
(variable `foreign`) what kind of handler it would like to initiate anyway,
so it might as well just inject the object (which makes the code easier to
follow, decreases bugs risk because there are less code paths)
This also gives the caller more control of the API handlers:
registerForeignSources will now be able to do more. Now it can e.g. create
1 object that is shared for multiple wikis (to do lookups for multiple
wikis at once)
Also renamed addApiHandler to setApiHandler (it just sets the value it needs
without checking if it already existed anyway)
Change-Id: Ie1814c5bf1a1f0e5607033beb506df67f3585b24
this.api is used in APIHandler.createNewFetchNotificationPromise,
so we should make sure it always has a valid this.api
Change-Id: Id476661fb427adbbb3c5741737c293c32ad8a27e
Allow marking notifications as read per 'section' (days) in the
Special:Notifications page.
Bug: T115528
Bug: T134204
Change-Id: I7324a2c693aa92b9327cf8ff98f125293d5fba10
Fetch cross-wiki notifications by asking the local API, but still
maintain the ability to send remote requests to the foreign wikis
for mark-as-read operations.
Bug: T130636
Change-Id: I48524cb9dff43257a401d7483e939edfb042b928
Notifications were being marked as read in response to a click event
in JavaScript, but that causes a jarring effect in the UI, and it's
not reliable (the browser could abort the AJAX request).
Instead, add ?markasread=XYZ to the end of every primary link URL,
where XYZ is the event ID.
Bug: T133975
Depends-On: Icb99d5479836fea25a47451b5a758dd71f642f71
Change-Id: I8047d121584b43e6172463a50ad0e0de5f7fa73c
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
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
Split the moment hack out into its own file and put it in
ext.echo.ui, so it gets picked up by both the desktop and
the mobile modules.
Bug: T133134
Change-Id: Ic5b3e63fb6941a310d85ea7776447d1d7153cf91
min-width and min-height are now set on icons. This breaks the ability
to scale icons down, so override these rules.
Change-Id: I6372f0fe17ccfd853bde497730c49cbcf9f89a41
To implement this, use PopupButtonWidget and override to handle hover
in addition to click.
Bug: T128937
Change-Id: I79f5bb5839491516b0a3f77630b481cd6c2cc3da
If we don't do this, the footer becomes slightly taller
when the image loads, which makes the popup clip incorrectly.
Change-Id: Ica84d704692676d884b847f8fe01c49319f04931
We were using momentjs here before (causing bug T123845),
but we switched to using a hack for short timestamps.
This hack didn't call convertNumber(), so we stopped performing
number formatting for languages that don't use Western Arabic
numerals (0-9).
Strictly, that regression "fixed" T123845 because it caused
0-9 to be used in all cases, including the case that that bug
asked for. This patch fixes the regression but preserves the
desired behavior for arwiki, since convertNumber() respects
$wgTranslateNumerals.
Bug: T123845
Change-Id: Ic9acb12f534e0f049e22577afe276f8bf68f691d
This caused notifications on mobile to show notifications for
both alert|message, as the type was always "all".
Bug: T130801
Change-Id: Ice245eb407ca360d8e882c0ba48cb7b3e0ecb851
The flyout loads no more than 25 notifications
from a given source. Using those in-memory notification
objects to count how many are currently unread (and
update the badge) produces a result of at most 25.
This patch extracts the responsibility or counting the
unread from the Model/Item/Groupitem structure into
a new UnreadNotificationCounter class. It receives
estimated updates from other components and synchronizes
with the server after markRead/markUnread operations
have completed.
Bug: T129726
Change-Id: I9af4defc00dd491ed2b355eb4e85073476e08ce7
Hover effects aren't the only thing that cause link underlining,
the "Underline links" preference can do this too.
We do still need the :hover selectors too, for specificity reasons.
Bug: T130793
Change-Id: I01c0eaee449470380f3bd752e509043c4580fea9
Followup to I7891eb3fb46b3 this should be merged only after
the changes in MobileFrontend in Ie592ca738ac2d82 are merged.
Change-Id: I0f28e0757170e8a5b12075d3e9a2343fea7e7155
We need to use it in more than just the context of mobile, and
there is nothing actually mobile-specific in it. Renaming the
class so it isn't awkward to use elsewhere.
This makes the ext.echo.ui.mobile module unnecessary, but
we leave it in until next patchset so that MobileFrontend
doesn't crash while we wait for the adjustments in
Ie592ca738ac2d8 to be merged.
Change-Id: I7891eb3fb46b350f0b325bf0a2b56b2cd55ff1d7
Add a mw.echo.ui.FooterNoticeWidget that includes a link to
a feedback survey, and three config variables:
* $wgEchoShowFooterNotice: Enable this feature per wiki
(Defaults to false)
* $wgEchoFooterNoticeURL: The URL for the survey
(Defaults to '')
* User preference 'echo-dismiss-feedback-alert': determines
whether the user permanently dismissed the feedback alert.
(Defaults to false)
Bug: T128937
Change-Id: I918a70beaba7b173e764519fe4fe0f780b61082d
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
This involves:
* Making this value no longer admin-configurable.
* Changing getNotificationCountForOutput to return only a single value
Since there is no + in the formatted value anymore, we can actually
use the same value for both.
This is a B/C break, but hopefully worth it to simplify the method
call.
For now, the excess parameter is just marked unused. It could be
removed at some point if the translations are updated.
This must be merged at the same time as:
* Flow - Ibfa56b1af9e8c56b4c5f900e0d487bc09688b2a2
* MobileFrontend - Ibf784b279d56773a227ff261b75f2b26125bbb63 (well, MF
can be merged first)
* translatewiki - I2a4b6938aed49e4101deb6b9351c43656a863490
Also, change 1 to One/one, per Siebrand on the task. This can easily
be dropped/undone if we don't want it.
Also, remove reference to no-longer-existent notification-page-linked-bundle
Bug: T127288
Change-Id: Iabeaae747f99980c0610d552f6b38f89d940b890
FloatableElement incorrectly believes it doesn't need to
position itself when its closest scrollable is the same as
the closest scrollable of the container. This causes
the dotdotdot menu to be placed at the top left of the screen
if the notifications popup is not scrollable. If it is scrollable,
everything works fine. This regression was introduced by I5b5d7936c4d.
Work around this by setting overflow-x: auto; on the popup body.
This is a no-op, but tricks OOUI into thinking that the popup
body is scrollable even when it visually isn't. We can't use
overflow-y for this, because we still need to set overflow-y: auto;
on the popup body to work around a Chrome bug where right-floated
elements don't move over when the scrollbar appears.
Bug: T130153
Change-Id: I8bd8a26a4931444a760d2159779240272c51f966
This is to wrap the mobile notifications in MobileFrontend with
a pendingElement and organize the API calls specifically for the
mixed popup in mobile.
Also added a specific 'ext.echo.ui.mobile' module so we don't
load unnecessary files for mobile.
Bug: T124188
Change-Id: I4a8be19a79b9e38c21907bb9d4123540a648c535
Add a 'mark as unread' to all unread notifications and allow them
to be marked unread. These notifications will no longer be automatically
marked as read when the pages they refer to are visited.
Bug: T73564
Change-Id: I677d3c0399e46fd7c35531df1cc0e61db2d4eb1b
We have a wrapper around logInteraction() called logNotificationImpressions()
that logs impressions uniquely (i.e. logs each notification impression only once),
but in addition to calling that (from NotificationsWidget), we were also manually
calling logInteraction() to log impressions from NotificationBadgeWidget
and NotificationGroupItemWidget. This resulted in two impression events
for every notification, each with different data, one of which is logged
only once and one of which can be logged multiple times.
Remove the manual logImpression() calls and route everything through
logNotificationImpressions(), which is called from only one place:
NotificationsWidget. Add support for logging foreign wikis to
logNotificationImpressions(), as it was previously missing.
This causes us to lose the notification type information in these
events, but that can also be derived after the fact by looking
up the event_id in the echo_event table.
Whether impression logging is even useful is another question,
but it certainly isn't useful if we log duplicate impression
events with different data.
Change-Id: I19b76a4ce796b21e9347dd9392af24918db82e18