Compare commits

...

2 Commits

@ -1,4 +1,5 @@
'use strict';
const React = require('react');
const create = require('create-react-class');
const Promise = require('bluebird');

@ -1,7 +1,6 @@
'use strict';
const React = require('react');
const create = require('create-react-class');
const jdenticon = require('jdenticon');
const sanitize = require('sanitize-html');
const Event = require('./events/Event.js');
@ -10,17 +9,7 @@ const Input = require('./input.js');
const User = require('./events/user.js');
const Loading = require('./loading.js');
jdenticon.config = {
lightness: {
color: [0.58, 0.66],
grayscale: [0.30, 0.90]
},
saturation: {
color: 0.66,
grayscale: 0.00
},
backColor: "#00000000"
};
const generateJdenticon = require("../lib/generate-jdenticon");
let eventFunctions = {
plaintext: function() {
@ -202,7 +191,7 @@ let EventGroup = create({
},
avatarRef: function(ref) {
jdenticon.update(ref, this.state.user.userId);
generateJdenticon(this.state.user.userId).update(ref);
},
render: function() {

@ -1,39 +1,17 @@
'use strict';
const React = require('react');
const create = require('create-react-class');
const jdenticon = require('jdenticon');
"use strict";
jdenticon.config = {
lightness: {
color: [0.58, 0.66],
grayscale: [0.30, 0.90]
},
saturation: {
color: 0.66,
grayscale: 0.00
},
backColor: "#00000000"
};
const React = require("react");
const create = require("create-react-class");
const generateJdenticon = require("../../lib/generate-jdenticon");
let User = create({
displayName: "user",
getInitialState: function() {
let icon = jdenticon.toSvg(this.props.user.userId, 200);
let match = icon.match(/#([a-f0-9]{6})/g);
let color = '#ff0000';
/* FIXME: Replace with a .find */
for(let i=match.length-1; i>= 0; i--) {
color = match[i];
let r = color.substr(1, 2);
let g = color.substr(3, 2);
let b = color.substr(5, 2);
if (r != g && g != b) { // not greyscale
break;
}
}
return {
color: color
/* FIXME: Cache this to speed it up */
color: generateJdenticon(this.props.user.userId).primaryColor()
};
},

@ -23,5 +23,5 @@ module.exports = function createApiRequester(apiUrl) {
}
});
});
}
};
};

@ -0,0 +1,49 @@
"use strict";
const jdenticon = require("jdenticon");
const defaultValue = require("default-value");
module.exports = function generateJdenticon(name) {
function setConfig() {
/* NOTE: This is a hack to ensure that any other code using the `jdenticon` library can't mess with our config, since it's set globally. This function gets called prior to *every* jdenticon-generating operation. */
jdenticon.config = {
lightness: {
color: [0.58, 0.66],
grayscale: [0.30, 0.90]
},
saturation: {
color: 0.66,
grayscale: 0.00
},
backColor: "#00000000"
};
}
return {
toSvg: function (size) {
setConfig();
return jdenticon.toSvg(name, size);
},
primaryColor: function () {
let svg = this.toSvg();
let color = svg.match(/#([a-f0-9]{6})/g).find((candidate) => {
let r = candidate.substr(1, 2);
let g = candidate.substr(3, 2);
let b = candidate.substr(5, 2);
let isGrayScale = (r === g && g === b);
return !isGrayScale;
});
return defaultValue(color, "#ff0000");
},
update: function (element) {
setConfig();
jdenticon.update(element, name);
}
}
};

@ -1,6 +1,9 @@
'use strict';
/*
Copyright 2015, 2016 OpenMarket Ltd
With modifications, by f0x
With modifications, by Sven Slootweg <admin@cryto.net>
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
@ -14,7 +17,6 @@ limitations under the License.
const Promise = require('bluebird');
const sanitize = require('sanitize-html');
//require("blueimp-canvas-to-blob");
const COLOR_REGEX = /^#[0-9a-fA-F]{6}$/;
/**
@ -36,29 +38,86 @@ const COLOR_REGEX = /^#[0-9a-fA-F]{6}$/;
* and a thumbnail key.
*/
function canvasToBlob(canvas, mimeType) {
return new Promise((resolve, _reject) => {
canvas.toBlob(function(blob) {
resolve(blob);
}, mimeType);
});
}
function awaitImageLoad(image) {
return new Promise((resolve, reject) => {
image.onload = function() {
resolve();
};
image.onerror = function(e) {
reject(e);
};
});
}
function awaitFileReader(dataUrl) {
return new Promise((resolve, reject) => {
const reader = new FileReader();
reader.onload = function(event) {
resolve(event.target.result);
};
reader.onerror = function(error) {
reject(error);
};
reader.readAsDataURL(dataUrl);
});
}
function awaitVideoLoad(video) {
return new Promise((resolve, reject) => {
video.onloadeddata = function() {
resolve({
width: video.videoWidth,
height: video.videoHeight
});
};
video.onerror = function(error) {
reject(error);
};
});
}
module.exports = {
createThumbnail: function(element, inputWidth, inputHeight, mimeType) {
return new Promise(function(resolve, reject) {
return Promise.try(() => {
const MAX_WIDTH = 800;
const MAX_HEIGHT = 600;
let targetWidth = inputWidth;
let targetHeight = inputHeight;
if (targetHeight > MAX_HEIGHT) {
targetWidth = Math.floor(targetWidth * (MAX_HEIGHT / targetHeight));
targetHeight = MAX_HEIGHT;
}
if (targetWidth > MAX_WIDTH) {
targetHeight = Math.floor(targetHeight * (MAX_WIDTH / targetWidth));
targetWidth = MAX_WIDTH;
}
const canvas = Object.assign(document.createElement("canvas"), {
width: targetWidth,
height: targetHeight
});
const canvas = document.createElement("canvas");
canvas.width = targetWidth;
canvas.height = targetHeight;
canvas.getContext("2d").drawImage(element, 0, 0, targetWidth, targetHeight);
canvas.toBlob(function(thumbnail) {
resolve({
return Promise.try(() => {
return canvasToBlob(canvas, mimeType);
}).then((thumbnail) => {
return {
info: {
thumbnail_info: {
w: targetWidth,
@ -70,8 +129,8 @@ module.exports = {
h: inputHeight,
},
thumbnail: thumbnail,
});
}, mimeType);
};
});
});
},
@ -82,20 +141,16 @@ module.exports = {
* @return {Promise} A promise that resolves with the html image element.
*/
loadImageElement: function(imageFile) {
return new Promise(function(resolve, reject) {
// Load the file into an html element
return Promise.try(() => {
const img = document.createElement("img");
const objectUrl = URL.createObjectURL(imageFile);
img.src = objectUrl;
// Once ready, create a thumbnail
img.onload = function() {
return Promise.try(() => {
return awaitImageLoad(img);
}).then(() => {
URL.revokeObjectURL(objectUrl);
resolve(img);
};
img.onerror = function(e) {
reject(e);
};
});
});
},
@ -106,29 +161,19 @@ module.exports = {
* @return {Promise} A promise that resolves with the video image element.
*/
loadVideoElement: function(videoFile) {
return new Promise(function(resolve, reject) {
// Load the file into an html element
const video = document.createElement("video");
const reader = new FileReader();
reader.onload = function(e) {
video.src = e.target.result;
// Once ready, returns its size
// Wait until we have enough data to thumbnail the first frame.
video.onloadeddata = function() {
video.width = video.videoWidth;
video.height = video.videoHeight;
resolve(video);
};
video.onerror = function(e) {
reject(e);
};
};
reader.onerror = function(e) {
reject(e);
};
reader.readAsDataURL(videoFile);
return Promise.try(() => {
return awaitFileReader(videoFile);
}).then((url) => {
const video = Object.assign(document.createElement("video"), {
src: url
});
return Promise.try(() => {
return awaitVideoLoad(video);
}).then((dimensions) => {
/* FIXME: Check whether this can be improved, it's a bit dirty to shoehorn the dimensions onto the video object like this */
return Object.assign(video, dimensions);
});
});
},
@ -163,7 +208,7 @@ module.exports = {
transformTags: { // custom to matrix
// add blank targets to all hyperlinks except vector URLs
'img': function(tagName, attribs) {
'img': function(tagName, _attribs) {
// Strip out imgs that aren't `mxc` here instead of using allowedSchemesByTag
// because transformTags is used _before_ we filter by allowedSchemesByTag and
// we don't want to allow images with `https?` `src`s.
@ -209,10 +254,7 @@ module.exports = {
Object.keys(customCSSMapper).forEach((customAttributeKey) => {
const cssAttributeKey = customCSSMapper[customAttributeKey];
const customAttributeValue = attribs[customAttributeKey];
if (customAttributeValue &&
typeof customAttributeValue === 'string' &&
COLOR_REGEX.test(customAttributeValue)
) {
if (customAttributeValue && typeof customAttributeValue === 'string' && COLOR_REGEX.test(customAttributeValue)) {
style += cssAttributeKey + ":" + customAttributeValue + ";";
delete attribs[customAttributeKey];
}

Loading…
Cancel
Save