mirror of
https://github.com/StarCitizenTools/mediawiki-skins-Citizen.git
synced 2024-09-23 10:19:43 +00:00
feat(Echo): ✨ upgrade Echo buttons for consistency
This is similiar to how it is handled in Vector. We are forcing the Echo button to render in the same way as it was initially. This took me so many hours sigh.
This commit is contained in:
parent
251109c712
commit
fdc6eaee20
|
@ -356,8 +356,9 @@ class SkinHooks implements
|
|||
$linkClass = $item['link-class'] ?? [];
|
||||
$newLinkClass = [
|
||||
// Allows Echo to react to clicks
|
||||
'mw-echo-notification-badge-nojs',
|
||||
'citizen-header__button'
|
||||
'citizen-echo-notification-badge',
|
||||
'citizen-header__button',
|
||||
'mw-echo-notification-badge-nojs'
|
||||
];
|
||||
if ( in_array( 'mw-echo-unseen-notifications', $linkClass ) ) {
|
||||
$newLinkClass[] = 'mw-echo-unseen-notifications';
|
||||
|
|
107
resources/skins.citizen.scripts/echo.js
Normal file
107
resources/skins.citizen.scripts/echo.js
Normal file
|
@ -0,0 +1,107 @@
|
|||
/**
|
||||
* Originally based on Vector
|
||||
*
|
||||
* Upgrades Echo for icon consistency.
|
||||
* Undos work inside Echo to replace our button.
|
||||
*
|
||||
* TODO: Switch to mw.hook( 'ext.echo.NotificationBadgeWidget.onInitialize' ) when we drop 1.39 support
|
||||
*/
|
||||
function init() {
|
||||
if ( document.querySelectorAll( '#pt-notifications-alert a, #pt-notifications-notice a' ).length !== 2 ) {
|
||||
return;
|
||||
}
|
||||
|
||||
const notifications = document.getElementById( 'p-notifications' );
|
||||
// Clone the icons so we can insert it back afterwards
|
||||
const alertIcon = notifications.querySelector( '#pt-notifications-alert > a > .citizen-ui-icon' ).cloneNode();
|
||||
const noticeIcon = notifications.querySelector( '#pt-notifications-notice > a > .citizen-ui-icon' ).cloneNode();
|
||||
|
||||
// When the Echo button is clicked, all of its children are reset back to the initial state.
|
||||
// This will re-upgrade the children of the Echo button
|
||||
const callChildSupportServices = ( anchor ) => {
|
||||
const badge = anchor.parentElement;
|
||||
// Wrap label in a span
|
||||
const label = document.createElement( 'span' );
|
||||
label.textContent = anchor.textContent;
|
||||
anchor.replaceChildren( label );
|
||||
// Add icon span back
|
||||
if ( badge.id === 'pt-notifications-alert' ) {
|
||||
anchor.prepend( alertIcon );
|
||||
anchor.classList.remove( 'oo-ui-icon-bell' );
|
||||
} else if ( badge.id === 'pt-notifications-notice' ) {
|
||||
anchor.prepend( noticeIcon );
|
||||
anchor.classList.remove( 'oo-ui-icon-tray' );
|
||||
}
|
||||
};
|
||||
|
||||
// Upgrade the Echo badge
|
||||
// This only needs to be run once at the Echo button init
|
||||
const setupFosterHome = ( badge, anchor ) => {
|
||||
badge.classList.add( 'mw-list-item' );
|
||||
anchor.classList.remove( 'mw-echo-notifications-badge' );
|
||||
anchor.classList.add( 'citizen-header__button', 'citizen-echo-notification-badge' );
|
||||
callChildSupportServices( anchor );
|
||||
};
|
||||
|
||||
// Whenever Echo kicks its children out from the button, undo what Echo did.
|
||||
const abuseObserver = new MutationObserver( ( mutations ) => {
|
||||
for ( const mutation of mutations ) {
|
||||
if ( mutation.type === 'childList' ) {
|
||||
const removedNodes = mutation.removedNodes;
|
||||
if ( removedNodes.length === 0 ) {
|
||||
return;
|
||||
}
|
||||
for ( const removedNode of removedNodes ) {
|
||||
if ( !( removedNode instanceof HTMLSpanElement ) || !removedNode.classList.contains( 'citizen-ui-icon' ) ) {
|
||||
return;
|
||||
}
|
||||
const anchor = mutation.target;
|
||||
callChildSupportServices( anchor );
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
|
||||
// Observe for Echo button init, it will only happen once per icon (so twice)
|
||||
let initObserved = 0;
|
||||
const initObserver = new MutationObserver( ( mutations ) => {
|
||||
for ( const mutation of mutations ) {
|
||||
// All Echo buttons are observed by abuseObserver, disconnect observer.
|
||||
if ( initObserved >= 2 ) {
|
||||
initObserver.disconnect();
|
||||
}
|
||||
if ( mutation.type === 'childList' ) {
|
||||
const addedNodes = mutation.addedNodes;
|
||||
if ( addedNodes.length === 0 ) {
|
||||
return;
|
||||
}
|
||||
for ( const addedNode of addedNodes ) {
|
||||
if ( !addedNode.classList.contains( 'mw-echo-ui-notificationBadgeButtonPopupWidget' ) ) {
|
||||
return;
|
||||
}
|
||||
const anchor = addedNode.firstElementChild;
|
||||
// Upgrade the badge immediately before Echo kicks its children out
|
||||
setupFosterHome( addedNode, anchor );
|
||||
// Observe Echo button
|
||||
abuseObserver.observe(
|
||||
anchor,
|
||||
{
|
||||
childList: true,
|
||||
subtree: true
|
||||
}
|
||||
);
|
||||
initObserved++;
|
||||
}
|
||||
}
|
||||
}
|
||||
} );
|
||||
initObserver.observe(
|
||||
notifications,
|
||||
{
|
||||
childList: true,
|
||||
subtree: true
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
module.exports = init;
|
|
@ -60,6 +60,7 @@ function initBodyContent( bodyContent ) {
|
|||
function main( window ) {
|
||||
const
|
||||
config = require( './config.json' ),
|
||||
echo = require( './echo.js' ),
|
||||
search = require( './search.js' ),
|
||||
dropdown = require( './dropdown.js' ),
|
||||
stickyHeader = require( './stickyHeader.js' ),
|
||||
|
@ -67,6 +68,7 @@ function main( window ) {
|
|||
share = require( './share.js' );
|
||||
|
||||
enableCssAnimations( window.document );
|
||||
echo();
|
||||
search.init( window );
|
||||
dropdown.init();
|
||||
stickyHeader.init();
|
||||
|
|
|
@ -132,7 +132,7 @@
|
|||
}
|
||||
|
||||
// Echo badge styles do not load before init in 1.39
|
||||
.mw-echo-notification-badge-nojs {
|
||||
.citizen-echo-notification-badge {
|
||||
.citizen-ui-icon + span {
|
||||
.sr-only;
|
||||
}
|
||||
|
|
|
@ -102,10 +102,6 @@
|
|||
&-empty {
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
a::after {
|
||||
filter: var( --filter-invert );
|
||||
}
|
||||
}
|
||||
|
||||
// HACK: Restore view button on revision page (#845)
|
||||
|
|
|
@ -77,7 +77,7 @@
|
|||
|
||||
// Language counter badge
|
||||
.citizen-page-languages {
|
||||
> .citizen-dropdown-summary {
|
||||
.citizen-dropdown-summary {
|
||||
position: relative; // So that the badge doesn't take a stroll to the far left
|
||||
|
||||
&::after {
|
||||
|
|
|
@ -158,6 +158,7 @@
|
|||
"callback": "MediaWiki\\Skins\\Citizen\\Hooks\\ResourceLoaderHooks::getCitizenResourceLoaderConfig"
|
||||
},
|
||||
"resources/skins.citizen.scripts/dropdown.js",
|
||||
"resources/skins.citizen.scripts/echo.js",
|
||||
"resources/skins.citizen.scripts/lastModified.js",
|
||||
"resources/skins.citizen.scripts/overflowElements.js",
|
||||
"resources/skins.citizen.scripts/scrollObserver.js",
|
||||
|
|
|
@ -8,87 +8,17 @@
|
|||
* Date: 2024-05-06
|
||||
*/
|
||||
|
||||
.mw-echo-notifications-badge {
|
||||
#pt-notifications-alert &,
|
||||
#pt-notifications-notice & {
|
||||
top: 0;
|
||||
width: var( --header-button-size );
|
||||
height: var( --header-button-size );
|
||||
margin: 0;
|
||||
background-color: transparent; // reset mw-list-item style from Citizen
|
||||
filter: var( --filter-invert );
|
||||
background-repeat: no-repeat;
|
||||
background-position: center;
|
||||
background-size: var( --header-icon-size );
|
||||
border-radius: var( --border-radius-base );
|
||||
opacity: var( --opacity-icon-base );
|
||||
|
||||
&:hover {
|
||||
opacity: var( --opacity-icon-base--hover );
|
||||
}
|
||||
|
||||
&:active {
|
||||
opacity: var( --opacity-icon-base--selected );
|
||||
}
|
||||
|
||||
&:focus {
|
||||
box-shadow: 0 0 0 1px var( --color-inverted-fixed ), 0 0 0 3px var( --color-progressive );
|
||||
opacity: var( --opacity-icon-base--selected );
|
||||
|
||||
&::after {
|
||||
border-color: var( --color-progressive );
|
||||
}
|
||||
}
|
||||
|
||||
&::after {
|
||||
top: 0;
|
||||
font-size: 0.65rem;
|
||||
background-color: var( --color-destructive );
|
||||
// Re-invert indicator color
|
||||
filter: var( --filter-invert );
|
||||
border-color: var( --color-destructive );
|
||||
border-radius: var( --border-radius-pill );
|
||||
}
|
||||
|
||||
&-dimmed {
|
||||
opacity: var( --opacity-icon-base--disabled );
|
||||
}
|
||||
|
||||
&.mw-echo-notifications-badge-all-read {
|
||||
opacity: var( --opacity-icon-base );
|
||||
|
||||
&:hover {
|
||||
opacity: var( --opacity-icon-base--hover );
|
||||
}
|
||||
|
||||
&:active {
|
||||
opacity: var( --opacity-icon-base--selected );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
&.oo-ui-flaggedElement-unseen,
|
||||
&.mw-echo-unseen-notifications {
|
||||
#pt-notifications-alert &::after {
|
||||
background-color: var( --color-destructive );
|
||||
}
|
||||
|
||||
#pt-notifications-notice &::after {
|
||||
background-color: var( --color-destructive );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Add quiet background hover states
|
||||
#pt-notifications-alert,
|
||||
#pt-notifications-notice {
|
||||
border-radius: var( --border-radius-base );
|
||||
|
||||
&:hover {
|
||||
background-color: var( --background-color-button-quiet--hover );
|
||||
}
|
||||
|
||||
&:active {
|
||||
background-color: var( --background-color-button-quiet--active );
|
||||
.citizen-echo-notification-badge {
|
||||
&:not( [ data-counter-text='1' ] )::after {
|
||||
position: absolute;
|
||||
top: var( --space-xxs );
|
||||
right: var( --space-xxs );
|
||||
box-sizing: content-box;
|
||||
width: 0.5rem;
|
||||
height: 0.5rem;
|
||||
content: '';
|
||||
background: var( --color-progressive );
|
||||
border: 4px solid var( --color-surface-0 );
|
||||
border-radius: 100%;
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue