merge-upstream: fix long tail of regressions from rewriting themes
This commit is contained in:
1 parent
a53431f4b7
commit
76adb02565
12 files changed
+66
-53
No files matched your search
@@ -17,7 +17,6 @@
|
||||
import addons from './generated/addon-manifests';
|
||||
import upstreamMeta from './generated/upstream-meta.json';
|
||||
import EventTargetShim from './event-target';
|
||||
import {isDark} from '../lib/themes';
|
||||
|
||||
const SETTINGS_KEY = 'tw:addons';
|
||||
const VERSION = 4;
|
||||
@@ -366,7 +365,7 @@ class SettingsStore extends EventTargetShim {
|
||||
const result = {
|
||||
core: {
|
||||
// Upstream property. We don't use this.
|
||||
lightTheme: !isDark(theme),
|
||||
lightTheme: !theme.isDark(),
|
||||
// Doesn't matter what we set this to
|
||||
version: `v1.0.0-tw-${upstreamMeta.commit}`
|
||||
},
|
||||
|
||||
@@ -75,5 +75,5 @@
|
||||
border-radius: 100%;
|
||||
box-sizing: border-box;
|
||||
transform-origin: center;
|
||||
transform: scale(85%);
|
||||
transform: scale(90%);
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import {connect} from 'react-redux';
|
||||
import check from './check.svg';
|
||||
import dropdownCaret from './dropdown-caret.svg';
|
||||
import {MenuItem, Submenu} from '../menu/menu.jsx';
|
||||
import {BLOCKS_HIGH_CONTRAST, BLOCKS_THREE, Theme} from '../../lib/themes/index.js';
|
||||
import {BLOCKS_DARK, BLOCKS_HIGH_CONTRAST, BLOCKS_THREE, Theme} from '../../lib/themes/index.js';
|
||||
import {openBlocksThemeMenu, blocksThemeMenuOpen, closeSettingsMenu} from '../../reducers/menus.js';
|
||||
import {setTheme} from '../../reducers/theme.js';
|
||||
import styles from './settings-menu.css';
|
||||
@@ -24,6 +24,11 @@ const options = defineMessages({
|
||||
defaultMessage: 'High Contrast',
|
||||
description: 'Name of the high contrast block colors.',
|
||||
id: 'tw.blockColors.highContrast'
|
||||
},
|
||||
[BLOCKS_DARK]: {
|
||||
defaultMessage: 'Dark REMOVE BEFORE MERGE',
|
||||
description: 'Name of Scratch\'s experimental dark block colors',
|
||||
id: 'tw.blockColors.dark'
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import DefaultMonitor from './default-monitor.jsx';
|
||||
import LargeMonitor from './large-monitor.jsx';
|
||||
import SliderMonitor from '../../containers/slider-monitor.jsx';
|
||||
import ListMonitor from '../../containers/list-monitor.jsx';
|
||||
import {Theme, getStageColorsForTheme} from '../../lib/themes/index.js';
|
||||
import {Theme} from '../../lib/themes/index.js';
|
||||
|
||||
import styles from './monitor.css';
|
||||
|
||||
@@ -33,7 +33,7 @@ const modes = {
|
||||
};
|
||||
|
||||
const getCategoryColor = (theme, category) => {
|
||||
const colors = getStageColorsForTheme(theme);
|
||||
const colors = theme.getStageBlockColors();
|
||||
return {
|
||||
background: colors[categoryColorMap[category]].primary,
|
||||
text: colors.text
|
||||
|
||||
@@ -446,7 +446,7 @@ class Blocks extends React.Component {
|
||||
targetCostumes[targetCostumes.length - 1].name,
|
||||
stageCostumes[stageCostumes.length - 1].name,
|
||||
targetSounds.length > 0 ? targetSounds[targetSounds.length - 1].name : '',
|
||||
getColorsForTheme(this.props.theme)
|
||||
this.props.theme.getBlockColors()
|
||||
);
|
||||
} catch {
|
||||
return null;
|
||||
@@ -766,7 +766,7 @@ Blocks.defaultOptions = {
|
||||
Blocks.defaultProps = {
|
||||
isVisible: true,
|
||||
options: Blocks.defaultOptions,
|
||||
theme: Theme.light()
|
||||
theme: Theme.light
|
||||
};
|
||||
|
||||
const mapStateToProps = state => ({
|
||||
|
||||
@@ -279,7 +279,7 @@ Monitor.propTypes = {
|
||||
y: PropTypes.number
|
||||
};
|
||||
Monitor.defaultProps = {
|
||||
theme: Theme.light()
|
||||
theme: Theme.light
|
||||
};
|
||||
const mapStateToProps = state => ({
|
||||
monitorLayout: state.scratchGui.monitorLayout,
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
const guiColors = {
|
||||
'motion-primary': '#ff4c4c',
|
||||
'motion-tertiary': '#cc3333',
|
||||
|
||||
'looks-secondary': '#ff4c4c',
|
||||
'looks-transparent': '#ff4d4d59',
|
||||
'looks-light-transparent': '#ff4d4d26',
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import {DEFAULT_THEME, getColorsForTheme, themeMap} from '.';
|
||||
import {BLOCKS_HIGH_CONTRAST, Theme} from '.';
|
||||
|
||||
const getBlockIconURI = extensionIcons => {
|
||||
if (!extensionIcons) return null;
|
||||
@@ -13,7 +13,7 @@ const getCategoryIconURI = extensionIcons => {
|
||||
};
|
||||
|
||||
// scratch-blocks colours has a pen property that scratch-gui uses for all extensions
|
||||
const getExtensionColors = theme => getColorsForTheme(theme).pen;
|
||||
const getExtensionColors = theme => theme.getBlockColors().pen;
|
||||
|
||||
/**
|
||||
* Applies extension color theme to categories.
|
||||
@@ -21,15 +21,14 @@ const getExtensionColors = theme => getColorsForTheme(theme).pen;
|
||||
* These colors are not seen if the category provides a blockIconURI.
|
||||
* @param {Array.<object>} dynamicBlockXML - XML for each category of extension blocks, returned from getBlocksXML
|
||||
* in the vm runtime.
|
||||
* @param {string} theme - Theme name
|
||||
* @param {Theme} theme - Theme name
|
||||
* @returns {Array.<object>} Dynamic block XML updated with colors.
|
||||
*/
|
||||
const injectExtensionCategoryTheme = (dynamicBlockXML, theme) => {
|
||||
// Don't do any manipulation for the default theme
|
||||
if (theme === DEFAULT_THEME) return dynamicBlockXML;
|
||||
if (theme.blocks !== BLOCKS_HIGH_CONTRAST) return dynamicBlockXML;
|
||||
|
||||
const extensionColors = getExtensionColors(theme);
|
||||
const extensionIcons = themeMap[theme].extensions;
|
||||
const extensionIcons = theme.getExtensions();
|
||||
const parser = new DOMParser();
|
||||
const serializer = new XMLSerializer();
|
||||
|
||||
@@ -57,7 +56,7 @@ const injectBlockIcons = (blockInfoJson, theme) => {
|
||||
if (!blockInfoJson.args0 || blockInfoJson.args0.length < 1 ||
|
||||
blockInfoJson.args0[0].type !== 'field_image') return blockInfoJson;
|
||||
|
||||
const extensionIcons = themeMap[theme].extensions;
|
||||
const extensionIcons = theme.getExtensions();
|
||||
const extensionId = blockInfoJson.type.substring(0, blockInfoJson.type.indexOf('_'));
|
||||
const blockIconURI = getBlockIconURI(extensionIcons[extensionId]);
|
||||
|
||||
@@ -80,12 +79,11 @@ const injectBlockIcons = (blockInfoJson, theme) => {
|
||||
* Applies extension color theme to static block json.
|
||||
* No changes are applied if called with the default theme, allowing extensions to provide their own colors.
|
||||
* @param {object} blockInfoJson - Static block json
|
||||
* @param {string} theme - Theme name
|
||||
* @param {Theme} theme - Theme name
|
||||
* @returns {object} Block info json with updated colors. The original blockInfoJson is not modified.
|
||||
*/
|
||||
const injectExtensionBlockTheme = (blockInfoJson, theme) => {
|
||||
// Don't do any manipulation for the default theme
|
||||
if (theme === DEFAULT_THEME) return blockInfoJson;
|
||||
if (theme.blocks !== BLOCKS_HIGH_CONTRAST) return blockInfoJson;
|
||||
|
||||
const extensionColors = getExtensionColors(theme);
|
||||
|
||||
|
||||
@@ -3,10 +3,6 @@
|
||||
/* This is for overriding some styles that don't really "belong" to any existing stylesheets */
|
||||
/* Try to use this sparingly, otherwise this will become unmaintainable again... */
|
||||
|
||||
:global(:root) {
|
||||
color-scheme: var(--color-scheme);
|
||||
}
|
||||
|
||||
/* popover is used by gui and paint */
|
||||
/* some of these are duplicated over there too; !important makes sure these win */
|
||||
:global(.Popover) {
|
||||
|
||||
@@ -7,7 +7,7 @@ import AddonHooks from '../../addons/hooks';
|
||||
const applyGuiColors = theme => {
|
||||
const doc = document.documentElement;
|
||||
|
||||
const defaultColors = Theme.light().getGuiColors();
|
||||
const defaultColors = Theme.light.getGuiColors();
|
||||
for (const [name, value] of Object.entries(defaultColors)) {
|
||||
doc.style.setProperty(`--${name}-default`, value);
|
||||
}
|
||||
@@ -17,6 +17,8 @@ const applyGuiColors = theme => {
|
||||
doc.style.setProperty(`--${name}`, value);
|
||||
}
|
||||
|
||||
doc.style.colorScheme = colors['color-scheme'];
|
||||
|
||||
// a horrible hack
|
||||
window.Recolor = {
|
||||
primary: colors['looks-secondary']
|
||||
|
||||
+34
-25
@@ -1,5 +1,4 @@
|
||||
import defaultsDeep from 'lodash.defaultsdeep';
|
||||
import {defineMessages} from 'react-intl';
|
||||
|
||||
import * as accentPurple from './accent/purple';
|
||||
import * as accentBlue from './accent/blue';
|
||||
@@ -10,7 +9,7 @@ import * as guiDark from './gui/dark';
|
||||
|
||||
import * as blocksThree from './blocks/three';
|
||||
import * as blocksHighContrast from './blocks/high-contrast';
|
||||
import * as blocksDark from './blocks/high-contrast';
|
||||
import * as blocksDark from './blocks/dark';
|
||||
|
||||
const ACCENT_PURPLE = 'purple';
|
||||
const ACCENT_BLUE = 'blue';
|
||||
@@ -39,39 +38,34 @@ const BLOCKS_MAP = {
|
||||
[BLOCKS_THREE]: {
|
||||
blocksMediaFolder: 'blocks-media/default',
|
||||
colors: blocksThree.blockColors,
|
||||
extensions: blocksThree.extensions
|
||||
extensions: blocksThree.extensions,
|
||||
useForStage: true
|
||||
},
|
||||
[BLOCKS_HIGH_CONTRAST]: {
|
||||
blocksMediaFolder: 'blocks-media/high-contrast',
|
||||
colors: defaultsDeep({}, blocksHighContrast.blockColors, defaultBlockColors),
|
||||
extensions: blocksHighContrast.extensions
|
||||
extensions: blocksHighContrast.extensions,
|
||||
useForStage: true
|
||||
},
|
||||
[BLOCKS_DARK]: {
|
||||
blocksMediaFolder: 'blocks-media/default',
|
||||
colors: defaultsDeep({}, blocksDark.blockColors, defaultBlockColors),
|
||||
extensions: blocksDark.extensions
|
||||
extensions: blocksDark.extensions,
|
||||
useForStage: false
|
||||
}
|
||||
};
|
||||
|
||||
class Theme {
|
||||
constructor (accent, gui, blocks) {
|
||||
// do not modify directly
|
||||
// do not modify these directly
|
||||
this.accent = Object.keys(ACCENT_MAP).includes(accent) ? accent : ACCENT_DEFAULT;
|
||||
this.gui = Object.keys(GUI_MAP).includes(gui) ? gui : GUI_DEFAULT;
|
||||
this.blocks = Object.keys(BLOCKS_MAP).includes(blocks) ? blocks : BLOCKS_DEFAULT;
|
||||
}
|
||||
|
||||
static light () {
|
||||
return new Theme(ACCENT_DEFAULT, GUI_LIGHT, BLOCKS_DEFAULT);
|
||||
}
|
||||
|
||||
static dark () {
|
||||
return new Theme(ACCENT_DEFAULT, GUI_DARK, BLOCKS_DEFAULT);
|
||||
}
|
||||
|
||||
static highContrast () {
|
||||
return new Theme(ACCENT_DEFAULT, GUI_DEFAULT, BLOCKS_HIGH_CONTRAST);
|
||||
}
|
||||
static light = new Theme(ACCENT_DEFAULT, GUI_LIGHT, BLOCKS_DEFAULT);
|
||||
static dark = new Theme(ACCENT_DEFAULT, GUI_DARK, BLOCKS_DEFAULT);
|
||||
static highContrast = new Theme(ACCENT_DEFAULT, GUI_DEFAULT, BLOCKS_HIGH_CONTRAST);
|
||||
|
||||
set (what, to) {
|
||||
if (what === 'accent') {
|
||||
@@ -89,13 +83,22 @@ class Theme {
|
||||
* @returns {string} a string that uniquely identifies this theme. Intended to be used as a react key.
|
||||
*/
|
||||
key () {
|
||||
return JSON.stringify(this);
|
||||
return `${this.accent}|${this.gui}|${this.blocks}`;
|
||||
}
|
||||
|
||||
getBlocksMediaFolder () {
|
||||
return BLOCKS_MAP[this.blocks].blocksMediaFolder;
|
||||
}
|
||||
|
||||
getGuiColors () {
|
||||
return defaultsDeep(
|
||||
{},
|
||||
ACCENT_MAP[this.accent].guiColors,
|
||||
GUI_MAP[this.gui].guiColors,
|
||||
guiLight.guiColors
|
||||
);
|
||||
}
|
||||
|
||||
getBlockColors () {
|
||||
return defaultsDeep(
|
||||
{},
|
||||
@@ -105,13 +108,19 @@ class Theme {
|
||||
);
|
||||
}
|
||||
|
||||
getGuiColors () {
|
||||
return defaultsDeep(
|
||||
{},
|
||||
ACCENT_MAP[this.accent].guiColors,
|
||||
GUI_MAP[this.gui].guiColors,
|
||||
guiLight.guiColors
|
||||
);
|
||||
getExtensions () {
|
||||
return BLOCKS_MAP[this.blocks].extensions;
|
||||
}
|
||||
|
||||
isDark () {
|
||||
return this.getGuiColors()['color-scheme'] === 'dark';
|
||||
}
|
||||
|
||||
getStageBlockColors () {
|
||||
if (BLOCKS_MAP[this.blocks].useForStage) {
|
||||
return this.getBlockColors();
|
||||
}
|
||||
return Theme.light.getBlockColors();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,13 +10,13 @@ const STORAGE_KEY = 'tw:theme';
|
||||
const systemPreferencesTheme = () => {
|
||||
if (window.matchMedia) {
|
||||
if (window.matchMedia(PREFERS_HIGH_CONTRAST_QUERY).matches) {
|
||||
return Theme.highContrast();
|
||||
return Theme.highContrast;
|
||||
}
|
||||
if (window.matchMedia(PREFERS_DARK_QUERY).matches) {
|
||||
return Theme.dark();
|
||||
return Theme.dark;
|
||||
}
|
||||
}
|
||||
return Theme.light();
|
||||
return Theme.light;
|
||||
};
|
||||
|
||||
/**
|
||||
@@ -28,9 +28,10 @@ const detectTheme = () => {
|
||||
|
||||
// Migrate legacy preferences
|
||||
if (local === 'dark') {
|
||||
return Theme.dark();
|
||||
return Theme.dark;
|
||||
}
|
||||
if (local === 'light') {
|
||||
return Theme.light;
|
||||
}
|
||||
|
||||
const parsed = JSON.parse(local);
|
||||
|
||||
Reference in new issue
Block a user