Add Vector night mode feature flag

Bug: T355065
Change-Id: Ica63eb61ee042e8684168f6787b27a5e58e38bee
This commit is contained in:
bwang 2024-01-31 15:11:51 -06:00 committed by Jon Robson
parent 1c2dc9cbd3
commit e964cbb785
6 changed files with 130 additions and 20 deletions

View file

@ -243,11 +243,6 @@ final class Constants {
*/
public const REQUIREMENT_FONT_SIZE = 'CustomFontSize';
/**
* @var string
*/
public const CONFIG_KEY_CLIENT_PREFERENCES = 'VectorClientPreferences';
/**
* @var string
*/
@ -263,6 +258,11 @@ final class Constants {
*/
public const PREF_KEY_CLIENT_PREFS_PINNED = 'vector-client-prefs-pinned';
/**
* @var string
*/
public const CONFIG_KEY_CLIENT_PREFERENCES = 'VectorClientPreferences';
/**
* @var string
*/
@ -273,6 +273,36 @@ final class Constants {
*/
public const REQUIREMENT_CLIENT_PREFERENCES = 'ClientPreferences';
/**
* @var string
*/
public const CONFIG_KEY_NIGHT_MODE = 'VectorNightMode';
/**
* @var string
*/
public const FEATURE_NIGHT_MODE = 'NightMode';
/**
* @var string
*/
public const REQUIREMENT_NIGHT_MODE = 'NightMode';
/**
* @var string
*/
public const PREF_KEY_NIGHT_MODE = 'vector-night-mode';
/**
* @var string
*/
public const REQUIREMENT_PREF_NIGHT_MODE = 'PrefNightMode';
/**
* @var string
*/
public const PREF_NIGHT_MODE = 'PrefNightMode';
/**
* @var string
*/

View file

@ -23,6 +23,7 @@
namespace MediaWiki\Skins\Vector\FeatureManagement;
use MediaWiki\MediaWikiServices;
use MediaWiki\Skins\Vector\Constants;
use MediaWiki\Skins\Vector\FeatureManagement\Requirements\SimpleRequirement;
use RequestContext;
use Wikimedia\Assert\Assert;
@ -130,22 +131,23 @@ class FeatureManager {
}
/**
* Gets font size user's preference value
* Gets user's preference value
*
* If user preference is not set or did not appear in config
* set it to default value we go back to defualt suffix value 1
* set it to default value we go back to defualt suffix value
* that will ensure that the feature will be enabled when requirements are met
*
* @param string $preferenceKey User preference key
* @return string
*/
public function getFontValueFromUserPreferenceForSuffix() {
public function getUserPreferenceValue( $preferenceKey ) {
$user = RequestContext::getMain()->getUser();
$userOptionsLookup = MediaWikiServices::getInstance()->getUserOptionsLookup();
return $userOptionsLookup->getOption(
$user,
'vector-font-size'
// This should be the same as `preferenceKey` in clientPreferences config
// 'resources/skins.vector.clientPreferences/config.json'
$preferenceKey
// For client preferences, this should be the same as `preferenceKey`
// in 'resources/skins.vector.js/clientPreferences.json'
);
}
@ -158,15 +160,22 @@ class FeatureManager {
return array_map( function ( $featureName ) {
// switch to lower case and switch from camel case to hyphens
$featureClass = ltrim( strtolower( preg_replace( '/[A-Z]([A-Z](?![a-z]))*/', '-$0', $featureName ) ), '-' );
$prefix = 'vector-feature-' . $featureClass . '-';
// Client side preferences
switch ( $featureClass ) {
case 'custom-font-size':
$suffixEnabled = 'clientpref-' . $this->getFontValueFromUserPreferenceForSuffix();
switch ( $featureName ) {
case CONSTANTS::FEATURE_FONT_SIZE:
$suffixEnabled = 'clientpref-' . $this->getUserPreferenceValue( CONSTANTS::PREF_KEY_FONT_SIZE );
$suffixDisabled = 'clientpref-0';
break;
case 'limited-width':
case 'toc-pinned':
case CONSTANTS::PREF_NIGHT_MODE:
$suffixEnabled = 'clientpref-' . $this->getUserPreferenceValue( CONSTANTS::PREF_KEY_NIGHT_MODE );
$suffixDisabled = 'clientpref-0';
// Must be hardcoded to 'skin-night-mode' to be consistent with Minerva
// So that editors can target the same class across skins
$prefix = 'skin-night-mode-';
break;
case CONSTANTS::FEATURE_LIMITED_WIDTH:
case CONSTANTS::FEATURE_TOC_PINNED:
$suffixEnabled = 'clientpref-1';
$suffixDisabled = 'clientpref-0';
break;
@ -176,7 +185,6 @@ class FeatureManager {
$suffixDisabled = 'disabled';
break;
}
$prefix = 'vector-feature-' . $featureClass . '-';
return $this->isFeatureEnabled( $featureName ) ?
$prefix . $suffixEnabled : $prefix . $suffixDisabled;
}, array_keys( $this->features ) );

View file

@ -561,6 +561,9 @@ class Hooks implements
'help-message' => 'vector-prefs-limited-width-help',
'hide-if' => [ '!==', 'skin', Constants::SKIN_NAME_MODERN ],
],
Constants::PREF_KEY_NIGHT_MODE => [
'type' => 'api'
],
];
$prefs += $vectorPrefs;
}

View file

@ -294,6 +294,48 @@ return [
]
);
// Feature: Night mode (T355065)
// ============================================
$featureManager->registerRequirement(
new OverridableConfigRequirement(
$services->getMainConfig(),
$context->getUser(),
$request,
Constants::CONFIG_KEY_NIGHT_MODE,
Constants::REQUIREMENT_NIGHT_MODE
)
);
$featureManager->registerFeature(
Constants::FEATURE_NIGHT_MODE,
[
Constants::REQUIREMENT_FULLY_INITIALISED,
Constants::REQUIREMENT_NIGHT_MODE
]
);
// Preference: Night mode (T355065)
// ============================================
$featureManager->registerRequirement(
new UserPreferenceRequirement(
$context->getUser(),
$services->getUserOptionsLookup(),
Constants::PREF_KEY_NIGHT_MODE,
Constants::REQUIREMENT_PREF_NIGHT_MODE,
$request,
$context->getTitle()
)
);
$featureManager->registerFeature(
Constants::PREF_NIGHT_MODE,
[
Constants::REQUIREMENT_FULLY_INITIALISED,
Constants::REQUIREMENT_NIGHT_MODE,
Constants::REQUIREMENT_PREF_NIGHT_MODE
]
);
return $featureManager;
}
];

View file

@ -81,6 +81,11 @@ function main( window ) {
if ( mw.user.isAnon() ) {
throw new Error( 'T335317: Unexpected state expected. This will cause a performance problem.' );
}
// Can be removed once wgVectorNightMode is removed.
if ( document.documentElement.classList.contains( 'vector-feature-night-mode-disabled' ) ) {
// @ts-ignore issues relating to delete operator are not relevant here.
delete clientPreferenceConfig[ 'skin-night-mode' ];
}
clientPreferences.render( clientPreferenceSelector, clientPreferenceConfig );
} );
}

View file

@ -167,7 +167,8 @@
"vector-main-menu-pinned": 1,
"vector-toc-pinned": 1,
"vector-client-prefs-pinned": 1,
"vector-font-size": 0
"vector-font-size": 0,
"vector-night-mode": 2
},
"HookHandlers": {
"VectorCentralAuthHooks": {
@ -351,9 +352,9 @@
"skin-night-mode-1-label",
"skin-night-mode-2-label",
"vector-feature-limited-width-name",
"vector-feature-custom-font-size-name",
"vector-feature-limited-width-0-label",
"vector-feature-limited-width-1-label",
"vector-feature-custom-font-size-name",
"vector-feature-custom-font-size-0-label",
"vector-feature-custom-font-size-1-label",
"vector-feature-custom-font-size-2-label"
@ -526,6 +527,14 @@
]
},
"config": {
"VectorNightMode": {
"value": {
"logged_in": false,
"logged_out": false,
"beta": false
},
"description": "@var array enables night mode."
},
"VectorClientPreferences": {
"value": {
"logged_in": false,
@ -545,6 +554,19 @@
"VectorUseIconWatch": {
"value": true
},
"VectorNightModePageOptions": {
"value": {
"mainpage": false,
"querystring": {
"action": "(history|edit|submit)",
"diff": ".+"
},
"namespaces": [
-1,
14
]
}
},
"VectorMaxWidthOptions": {
"value": {
"exclude": {