switch Tinter from using dispatch to a synchronous update when changing the colourscheme, to avoid CSS getting out of sync with SVG colours
This commit is contained in:
parent
4fb31662e1
commit
8db14bde60
4 changed files with 60 additions and 17 deletions
|
@ -15,11 +15,14 @@ limitations under the License.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
var dis = require("./dispatcher");
|
var dis = require("./dispatcher");
|
||||||
|
var sdk = require("./index");
|
||||||
|
|
||||||
// FIXME: these vars should be bundled up and attached to
|
// FIXME: these vars should be bundled up and attached to
|
||||||
// module.exports otherwise this will break when included by both
|
// module.exports otherwise this will break when included by both
|
||||||
// react-sdk and apps layered on top.
|
// react-sdk and apps layered on top.
|
||||||
|
|
||||||
|
var DEBUG = 0;
|
||||||
|
|
||||||
// The colour keys to be replaced as referred to in SVGs
|
// The colour keys to be replaced as referred to in SVGs
|
||||||
var keyRgb = [
|
var keyRgb = [
|
||||||
"rgb(118, 207, 166)", // Vector Green
|
"rgb(118, 207, 166)", // Vector Green
|
||||||
|
@ -75,6 +78,7 @@ var svgAttrs = [
|
||||||
var cached = false;
|
var cached = false;
|
||||||
|
|
||||||
function calcCssFixups() {
|
function calcCssFixups() {
|
||||||
|
if (DEBUG) console.log("calcSvgFixups start");
|
||||||
for (var i = 0; i < document.styleSheets.length; i++) {
|
for (var i = 0; i < document.styleSheets.length; i++) {
|
||||||
var ss = document.styleSheets[i];
|
var ss = document.styleSheets[i];
|
||||||
if (!ss) continue; // well done safari >:(
|
if (!ss) continue; // well done safari >:(
|
||||||
|
@ -105,13 +109,16 @@ function calcCssFixups() {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (DEBUG) console.log("calcSvgFixups end");
|
||||||
}
|
}
|
||||||
|
|
||||||
function applyCssFixups() {
|
function applyCssFixups() {
|
||||||
|
if (DEBUG) console.log("applyCssFixups start");
|
||||||
for (var i = 0; i < cssFixups.length; i++) {
|
for (var i = 0; i < cssFixups.length; i++) {
|
||||||
var cssFixup = cssFixups[i];
|
var cssFixup = cssFixups[i];
|
||||||
cssFixup.style[cssFixup.attr] = colors[cssFixup.index];
|
cssFixup.style[cssFixup.attr] = colors[cssFixup.index];
|
||||||
}
|
}
|
||||||
|
if (DEBUG) console.log("applyCssFixups end");
|
||||||
}
|
}
|
||||||
|
|
||||||
function hexToRgb(color) {
|
function hexToRgb(color) {
|
||||||
|
@ -135,6 +142,7 @@ function rgbToHex(rgb) {
|
||||||
|
|
||||||
module.exports = {
|
module.exports = {
|
||||||
tint: function(primaryColor, secondaryColor, tertiaryColor) {
|
tint: function(primaryColor, secondaryColor, tertiaryColor) {
|
||||||
|
|
||||||
if (!cached) {
|
if (!cached) {
|
||||||
calcCssFixups();
|
calcCssFixups();
|
||||||
cached = true;
|
cached = true;
|
||||||
|
@ -173,11 +181,19 @@ module.exports = {
|
||||||
|
|
||||||
colors = [primaryColor, secondaryColor, tertiaryColor];
|
colors = [primaryColor, secondaryColor, tertiaryColor];
|
||||||
|
|
||||||
|
if (DEBUG) console.log("Tinter.tint");
|
||||||
|
|
||||||
// go through manually fixing up the stylesheets.
|
// go through manually fixing up the stylesheets.
|
||||||
applyCssFixups();
|
applyCssFixups();
|
||||||
|
|
||||||
// tell all the SVGs to go fix themselves up
|
// tell all the SVGs to go fix themselves up
|
||||||
dis.dispatch({ action: 'tint_update' });
|
// we don't do this as a dispatch otherwise it will visually lag
|
||||||
|
var TintableSvg = sdk.getComponent("elements.TintableSvg");
|
||||||
|
if (TintableSvg.mounts) {
|
||||||
|
Object.keys(TintableSvg.mounts).forEach((id) => {
|
||||||
|
TintableSvg.mounts[id].tint();
|
||||||
|
});
|
||||||
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
// XXX: we could just move this all into TintableSvg, but as it's so similar
|
// XXX: we could just move this all into TintableSvg, but as it's so similar
|
||||||
|
@ -189,6 +205,7 @@ module.exports = {
|
||||||
// updated would be a PITA, so just brute-force search for the
|
// updated would be a PITA, so just brute-force search for the
|
||||||
// key colour; cache the element and apply.
|
// key colour; cache the element and apply.
|
||||||
|
|
||||||
|
if (DEBUG) console.log("calcSvgFixups start for " + svgs);
|
||||||
var fixups = [];
|
var fixups = [];
|
||||||
for (var i = 0; i < svgs.length; i++) {
|
for (var i = 0; i < svgs.length; i++) {
|
||||||
var svgDoc;
|
var svgDoc;
|
||||||
|
@ -223,14 +240,17 @@ module.exports = {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (DEBUG) console.log("calcSvgFixups end");
|
||||||
|
|
||||||
return fixups;
|
return fixups;
|
||||||
},
|
},
|
||||||
|
|
||||||
applySvgFixups: function(fixups) {
|
applySvgFixups: function(fixups) {
|
||||||
|
if (DEBUG) console.log("applySvgFixups start for " + fixups);
|
||||||
for (var i = 0; i < fixups.length; i++) {
|
for (var i = 0; i < fixups.length; i++) {
|
||||||
var svgFixup = fixups[i];
|
var svgFixup = fixups[i];
|
||||||
svgFixup.node.setAttribute(svgFixup.attr, colors[svgFixup.index]);
|
svgFixup.node.setAttribute(svgFixup.attr, colors[svgFixup.index]);
|
||||||
}
|
}
|
||||||
|
if (DEBUG) console.log("applySvgFixups end");
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
|
@ -600,13 +600,15 @@ module.exports = React.createClass({
|
||||||
var theAlias = MatrixTools.getCanonicalAliasForRoom(room);
|
var theAlias = MatrixTools.getCanonicalAliasForRoom(room);
|
||||||
if (theAlias) presentedId = theAlias;
|
if (theAlias) presentedId = theAlias;
|
||||||
|
|
||||||
var color_scheme_event = room.getAccountData("org.matrix.room.color_scheme");
|
// No need to do this given RoomView triggers it itself...
|
||||||
var color_scheme = {};
|
// var color_scheme_event = room.getAccountData("org.matrix.room.color_scheme");
|
||||||
if (color_scheme_event) {
|
// var color_scheme = {};
|
||||||
color_scheme = color_scheme_event.getContent();
|
// if (color_scheme_event) {
|
||||||
// XXX: we should validate the event
|
// color_scheme = color_scheme_event.getContent();
|
||||||
}
|
// // XXX: we should validate the event
|
||||||
Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color);
|
// }
|
||||||
|
// console.log("Tinter.tint from _viewRoom");
|
||||||
|
// Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (eventId) {
|
if (eventId) {
|
||||||
|
|
|
@ -212,7 +212,9 @@ module.exports = React.createClass({
|
||||||
|
|
||||||
window.removeEventListener('resize', this.onResize);
|
window.removeEventListener('resize', this.onResize);
|
||||||
|
|
||||||
Tinter.tint(); // reset colourscheme
|
// no need to do this as Dir & Settings are now overlays. It just burnt CPU.
|
||||||
|
// console.log("Tinter.tint from RoomView.unmount");
|
||||||
|
// Tinter.tint(); // reset colourscheme
|
||||||
},
|
},
|
||||||
|
|
||||||
onAction: function(payload) {
|
onAction: function(payload) {
|
||||||
|
@ -346,6 +348,7 @@ module.exports = React.createClass({
|
||||||
color_scheme = color_scheme_event.getContent();
|
color_scheme = color_scheme_event.getContent();
|
||||||
// XXX: we should validate the event
|
// XXX: we should validate the event
|
||||||
}
|
}
|
||||||
|
console.log("Tinter.tint from updateTint");
|
||||||
Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color);
|
Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color);
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -354,6 +357,7 @@ module.exports = React.createClass({
|
||||||
if (event.getType === "org.matrix.room.color_scheme") {
|
if (event.getType === "org.matrix.room.color_scheme") {
|
||||||
var color_scheme = event.getContent();
|
var color_scheme = event.getContent();
|
||||||
// XXX: we should validate the event
|
// XXX: we should validate the event
|
||||||
|
console.log("Tinter.tint from onRoomAccountData");
|
||||||
Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color);
|
Tinter.tint(color_scheme.primary_color, color_scheme.secondary_color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -912,6 +916,7 @@ module.exports = React.createClass({
|
||||||
},
|
},
|
||||||
|
|
||||||
onCancelClick: function() {
|
onCancelClick: function() {
|
||||||
|
console.log("updateTint from onCancelClick");
|
||||||
this.updateTint();
|
this.updateTint();
|
||||||
this.setState({editingRoomSettings: false});
|
this.setState({editingRoomSettings: false});
|
||||||
},
|
},
|
||||||
|
@ -1179,6 +1184,7 @@ module.exports = React.createClass({
|
||||||
_gatherTimelinePanelRef: function(r) {
|
_gatherTimelinePanelRef: function(r) {
|
||||||
this.refs.messagePanel = r;
|
this.refs.messagePanel = r;
|
||||||
if(r) {
|
if(r) {
|
||||||
|
console.log("updateTint from RoomView._gatherTimelinePanelRef");
|
||||||
this.updateTint();
|
this.updateTint();
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -18,10 +18,9 @@ limitations under the License.
|
||||||
|
|
||||||
var React = require('react');
|
var React = require('react');
|
||||||
var ReactDOM = require("react-dom");
|
var ReactDOM = require("react-dom");
|
||||||
var dis = require("../../../dispatcher");
|
|
||||||
var Tinter = require("../../../Tinter");
|
var Tinter = require("../../../Tinter");
|
||||||
|
|
||||||
module.exports = React.createClass({
|
var TintableSvg = React.createClass({
|
||||||
displayName: 'TintableSvg',
|
displayName: 'TintableSvg',
|
||||||
|
|
||||||
propTypes: {
|
propTypes: {
|
||||||
|
@ -31,28 +30,42 @@ module.exports = React.createClass({
|
||||||
className: React.PropTypes.string,
|
className: React.PropTypes.string,
|
||||||
},
|
},
|
||||||
|
|
||||||
|
statics: {
|
||||||
|
// list of currently mounted TintableSvgs
|
||||||
|
mounts: {},
|
||||||
|
idSequence: 0,
|
||||||
|
},
|
||||||
|
|
||||||
componentWillMount: function() {
|
componentWillMount: function() {
|
||||||
this.fixups = [];
|
this.fixups = [];
|
||||||
this.dispatcherRef = dis.register(this.onAction);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
componentDidMount: function() {
|
componentDidMount: function() {
|
||||||
|
this.id = TintableSvg.idSequence++;
|
||||||
|
TintableSvg.mounts[this.id] = this;
|
||||||
// we can't use onLoad on object due to https://github.com/facebook/react/pull/5781
|
// we can't use onLoad on object due to https://github.com/facebook/react/pull/5781
|
||||||
// so handle it with pure DOM instead
|
// so handle it with pure DOM instead
|
||||||
ReactDOM.findDOMNode(this).addEventListener('load', this.onLoad);
|
ReactDOM.findDOMNode(this).addEventListener('load', this.onLoad);
|
||||||
},
|
},
|
||||||
|
|
||||||
componentWillUnmount: function() {
|
componentWillUnmount: function() {
|
||||||
|
delete TintableSvg.mounts[this.id];
|
||||||
ReactDOM.findDOMNode(this).removeEventListener('load', this.onLoad);
|
ReactDOM.findDOMNode(this).removeEventListener('load', this.onLoad);
|
||||||
dis.unregister(this.dispatcherRef);
|
|
||||||
},
|
},
|
||||||
|
|
||||||
onAction: function(payload) {
|
shouldComponentUpdate: function(nextProps, nextState) {
|
||||||
if (payload.action !== 'tint_update') return;
|
// XXX: no dynamic TintableSvgs for now; speed above all else
|
||||||
|
return false;
|
||||||
|
},
|
||||||
|
|
||||||
|
tint: function() {
|
||||||
|
// TODO: only bother running this if the global tint settings have changed
|
||||||
|
// since we loaded!
|
||||||
Tinter.applySvgFixups(this.fixups);
|
Tinter.applySvgFixups(this.fixups);
|
||||||
},
|
},
|
||||||
|
|
||||||
onLoad: function(event) {
|
onLoad: function(event) {
|
||||||
|
// console.log("TintableSvg.onLoad for " + this.props.src);
|
||||||
this.fixups = Tinter.calcSvgFixups([event.target]);
|
this.fixups = Tinter.calcSvgFixups([event.target]);
|
||||||
Tinter.applySvgFixups(this.fixups);
|
Tinter.applySvgFixups(this.fixups);
|
||||||
},
|
},
|
||||||
|
@ -67,3 +80,5 @@ module.exports = React.createClass({
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
module.exports = TintableSvg;
|
Loading…
Add table
Add a link
Reference in a new issue