add findInTree

This commit is contained in:
Zack Rauen 2018-08-13 16:38:13 -04:00
parent d04aa313fc
commit 3714e71297
2 changed files with 42 additions and 1 deletions

View File

@ -177,8 +177,10 @@ export default new class E2EE extends BuiltinModule {
renderMessageContent(component, args, retVal) {
if (!component.props.message.bd_encrypted) return;
const buttons = Utils.findInReactTree(retVal, m => Array.isArray(m) && m[1].props && m[1].props.currentUserId);
if (!buttons) return;
try {
retVal.props.children[0].props.children.props.children.props.children.unshift(VueInjector.createReactElement(E2EEMessageButton));
buttons.unshift(VueInjector.createReactElement(E2EEMessageButton));
} catch (err) {
Logger.err('E2EE', err.message);
}

View File

@ -53,6 +53,45 @@ export class Utils {
return camelCased;
}
/**
* Finds a value, subobject, or array from a tree that matches a specific filter. Great for patching render functions.
* @param {object} tree React tree to look through. Can be a rendered object or an internal instance.
* @param {callable} searchFilter Filter function to check subobjects against.
*/
static findInReactTree(tree, searchFilter) {
return this.findInTree(tree, searchFilter, {walkable: ['props', 'children', 'child', 'sibling']});
}
/**
* Finds a value, subobject, or array from a tree that matches a specific filter.
* @param {object} tree Tree that should be walked
* @param {callable} searchFilter Filter to check against each object and subobject
* @param {object} options Additional options to customize the search
* @param {Array<string>|null} [options.walkable=null] Array of strings to use as keys that are allowed to be walked on. Null value indicates all keys are walkable
* @param {Array<string>} [options.ignore=[]] Array of strings to use as keys to exclude from the search, most helpful when `walkable = null`.
*/
static findInTree(tree, searchFilter, {walkable = null, ignore = []}) {
if (searchFilter(tree)) return tree;
if (typeof tree !== "object" || tree == null) return undefined;
let tempReturn = undefined;
if (tree instanceof Array) {
for (let value of tree) {
tempReturn = this.findInTree(value, searchFilter, {walkable, ignore});
if (typeof tempReturn != "undefined") return tempReturn;
}
}
else {
const toWalk = walkable == null ? Object.keys(tree) : walkable;
for (let key of toWalk) {
if (!tree.hasOwnProperty(key) || ignore.includes(key)) continue;
tempReturn = this.findInTree(tree[key], searchFilter, {walkable, ignore});
if (typeof tempReturn != "undefined") return tempReturn;
}
}
return tempReturn;
}
/**
* Checks if two or more values contain the same data.
* @param {Any} ...value The value to compare