I'm trying to replace the send icon on the WebChat. I'm able to change the colors of the existing icon but how could I replace the SVG image by another one?
If you aren't looking to fork and build the repo, an alternative is to change the element directly in the html. Generally speaking, changing the DOM directly in a React environment is not best practice, however, in this case, the results appear to be stable.
There is also an open issue on the BotFramework-WebChat repo (#1839) that is discussing making the sendBox customizable. No ETA on when that might happen, but something to keep in mind.
To include this on your page, add the code starting at const parent. Be sure to set your image size to 28x28 if you want to maintain the same size as the current arrow.
<script>
( async function () {
const res = await fetch( 'http://somesite/directline/token', { method: 'POST' } );
const { token } = await res.json();
[...]
document.querySelector( '#webchat > *' ).focus();
const parent = document.getElementsByClassName( 'main' )
const child = parent[0].children[2].getElementsByTagName('svg');
const svg = document.createElementNS("http://www.w3.org/2000/svg", "svg");
const img = document.createElement("img");
img.src= 'bot - small.png';
svg.setAttribute('height', '28');
svg.setAttribute('width', '28');
svg.appendChild(img);
child[0].replaceWith(img);
}
)().catch( err => console.error( err ) );
</script>
Hope of help!
It looks like the icon cannot be changed as a setting currently.
But you can still fork the repository and change the icon, its definition is located here: https://github.com/microsoft/BotFramework-WebChat/blob/master/packages/component/src/SendBox/Assets/SendIcon.js
import React from 'react';
const SendIcon = () => (
<svg height={28} viewBox="0 0 45.7 33.8" width={28}>
<path clipRule="evenodd" d="M8.55 25.25l21.67-7.25H11zm2.41-9.47h19.26l-21.67-7.23zm-6 13l4-11.9L5 5l35.7 11.9z" />
</svg>
);
export default SendIcon;
Related
I'm completely new to this, and I don't know how to scale my texture to make it look smaller. it is a seamless texture. The three methods that come from materials do work well but the ones that have to do with texture don't do anything, surely it will be silly, but I'm starting to program and I don't know how to do it.
<mesh geometry={nodes.BON_GRAVA.geometry}
material={materials.BON_GRAVA}
material-map={useTexture("Gravel_001_BaseColor.jpg")}(works)
material-metalness={0.0} (works)
material-roughness={1.0} (works)
material-roughnessMap={useTexture("Gravel_001_Roughness.jpg")} (works)
material-normalMap={useTexture("Gravel_001_Normal.jpg")} (works)
material-aoMap={useTexture("Gravel_001_AmbientOcclusion.jpg")} (works)
This is me trying to do something, sorry
I've been trying .repeat, .offset, .wrapS but I don't know how the syntax for THREE methods works since it's a file gltfjsx + react
Call the useTexture hook at the top, then you can modify the Texture's (when the component mounts) with a useEffect hook: (be sure to set the needsUpdate flag to true on the Texture after any changes)
export function Component() {
const color = useTexture("Gravel_001_BaseColor.jpg");
const roughness = useTexture("Gravel_001_Roughness.jpg");
const normal = useTexture("Gravel_001_Normal.jpg");
const ao = useTexture("Gravel_001_AmbientOcclusion.jpg");
useEffect(() => {
color.repeat = new Vector2(1, 1);
color.wrapS = RepeatWrapping;
color.wrapT = RepeatWrapping;
color.needsUpdate = true; // don't forget this!
}, [color])
return (
<mesh
geometry={nodes.BON_GRAVA.geometry}
material={materials.BON_GRAVA}
material-map={color}
material-metalness={0.0}
material-roughness={1.0}
material-roughnessMap={roughness}
material-normalMap={normal}
material-aoMap={ao}
/>
)
}
I imported a 3D model from Mixamo with some animations and was wondering how to perform does animations in place?
The GLTF file I created from npx gltfjsx:
const { nodes, materials, animations } = useGLTF("/Mannequin.glb");
const { actions } = useAnimations(animations, heroRef);
return (
<>
<group ref={heroRef} dispose={null}>
<group rotation={[Math.PI / 2, 0, 0]} scale={0.01}>
<primitive object={nodes.mixamorig1Hips} />
<skinnedMesh
geometry={nodes.Ch36.geometry}
material={materials.Ch36_Body}
skeleton={nodes.Ch36.skeleton}
/>
</group>
{/* <gridHelper args={[25, 25]}/> */}
</group>
</>
);
}
useGLTF.preload("/Mannequin.glb");
For example, I would like the model to perform the run animation without changing locations (running on the spot) so that if I can perform user controls that translate the model and with the animation looping, it would look like they were actually running.
Are there any ways to do this? I have searched and could not find anything.
useEffect(() => {
console.log(actions) // find out the name of your action
actions.someAction.play()
});
This will make the animation play in place, if it was exported like that from mixamo, there is a setting.
Then you can put a around your mesh and make it move based on your control
I couldn't use console.log(actions) to see available actions as they were undefined and I had {} in console. My code was:
const { actions } = useAnimations(animations, group);
useEffect(() => {
console.log(actions);
}, [actions]);
So I digged inside into useAnimations source code and saw two things:
actions object is not being updated, only it's properties, so useEffect doesn't trigger when ref updates.
if ref.current is undefined (as for first render) properties are undefined. that's why I saw {} in console.
So I changed my code to:
const { actions } = useAnimations(animations, group);
useEffect(() => {
console.log(Object.keys(actions));
}, [actions]);
That's how I saw that my animation names were: ['Female_Idle', 'Female_Talk']
And
const { actions } = useAnimations(animations, group);
const action = actions['Female_Idle'];
useEffect(() => {
if (action) action.play();
}, [action]);
In order to play action, when ref updates. That did the trick.
Hi I have to drag a component which is outside a frame and drop into a iframe body(dragable source)
but it is not draging my component into iframe dragable source
this is code which is am using for get into the iframe and it is working means it is going into the iframe and finding element
const getIframeDocument = () => {
return cy.get(".gjs-frame").its("0.contentDocument").should("exist");
};
const getIframeBody = () => {
// get the document
return (
getIframeDocument()
// automatically retries until body is loaded
.its("body")
.should("not.be.undefined")
// wraps "body" DOM element to allow
// chaining more Cypress commands, like ".find(...)"
.then(cy.wrap)
);
};
and
for drag and drop into iframe like this
getIframeBody().find("#wrapper").as("Target");
cy.get('[title="Url"]').drag("#Target");
this is not giving me any error this drag function working but at the same time drag and drop is not happening
drag and drop execution pic must see this
you can do this by using this code. You just need to change selectors according to your website.
// Define Locators.
drag_element = '.blockbuilder-content-tools .blockbuilder-content-tool:nth-
child(6)';
drop_element = '#u_body #u_row_2';
text_indentation = '[aria-label="Align center"]';
new_box_text = 'This is a new Text block. Change the text.'
// Get iframe body and then drag & drop element.
iframe_interaction(){
let ifm = cy.get('iframe');
ifm
.should(iframe => expect(iframe.contents().find('body')))
.then(iframe => cy.wrap(iframe.contents().find('body')))
.within({}, $iframe => {
cy.get(this.drag_element).drag(this.drop_element, { force: true })
cy.contains(this.new_box_text).dblclick({force: true})
cy.get(this.text_indentation).click()
})
Github Link: https://github.com/sardar-usman/Cypress--Drag-and-Drop
I know that for CKEditor 4, you can get the textarea data like this:
var content = CKEDITOR.instances['comment'].getData();
How is this done for CKEditor 5?
You can find the answer in the Basic API guide.
Basically, in CKEditor 5 there's no single global editors repository (like the old CKEDITOR.instances global variable). This means that you need to keep the reference to the editor that you created and use that reference once you'll want to retrieve the data:
ClassicEditor
.create( document.querySelector( '#editor' ) )
.then( editor => {
editor.getData(); // -> '<p>Foo!</p>'
} )
.catch( error => {
console.error( error );
} );
If you need to retrieve the data on some other occasions (who would read it just after initializing the editor, right? ;)), then save the reference to the editor in some shared object of your application's state or some variable in the scope:
let theEditor;
ClassicEditor
.create( document.querySelector( '#editor' ) )
.then( editor => {
theEditor = editor; // Save for later use.
} )
.catch( error => {
console.error( error );
} );
function getDataFromTheEditor() {
return theEditor.getData();
}
See this JSFiddle: https://jsfiddle.net/2h2rq5u2/
EDIT: If you need to manage more than one editor instance, see CKEDITOR 5 get editor instances.
Declare a global variable and then use editor.getData(). Something like this:
var editor;
ClassicEditor
.create(document.querySelector('#editor'))
.then(editor => {
editor=editor;
})
.catch(error => {
console.error(error);
});
Then, in your event handler, this should work:
editor.getData();
I ran into what felt like a unique situation where I was loading multiple instances of CKeditor5 on a page but I also had features to dynamically add/remove/rearrange text areas that had editors applied to them.
Creating an array that contained all the instances was manageable but also a bit more complicated to keep track of when adding/removing/rearrange editor instances.
I instead decided to obtain the innerHTML of the editor instances by selecting all .ck-editor__editable classes and iterating over them to check the content.
document.querySelector("button[type='submit']").addEventListener('click', (event) => {
event.preventDefault();
const domEditableElements = document.querySelectorAll('.ck-editor__editable');
for (let i = 0; i < domEditableElements.length; ++i) {
let elementData = domEditableElements[i].innerHTML
if (elementData === '<p><br data-cke-filler="true"></p>') {
console.log(`Field ${i} is empty`);
}
}
});
Console logging indicated that ck-editor stored <p><br data-cke-filler="true"></p> in blank fields.
I have two presentational components. The first, called Category simply renders a React Native ListView component after doing a bit of set-up work.
The second component, Book, simply displays the data as text, with an image that should be fetched through the network.
Unfortunately, the Image doesn't seem to be displaying at all. Can someone help me get the image to display? Below, please find the Category and Book component definition, as well as a sample of the props being past to Book.
Category.js
import React from 'react';
import { ListView, Text } from 'react-native';
import _ from 'lodash';
import { camelizeKeys } from 'humps';
import Book from './Book';
const Category = ({ category }) => {
let element;
if (!_.isEmpty(category)) { // if data is available
const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
const camelCasedBooks = camelizeKeys(category.results.books);
const data = ds.cloneWithRows(camelCasedBooks);
element = (
<ListView
dataSource={data}
enableEmptySections
renderRow={(book) => <Book {...book} />}
/>
);
} else { // if data is not available
element = (
<Text>Loading</Text>
);
}
return element;
};
Category.propTypes = {
category: React.PropTypes.object.isRequired,
};
export default Category;
Book.js
import React from 'react';
import { Image, Text, View } from 'react-native';
const Book = ({ author, bookImage, description, title }) =>
<View>
<Text>
{author}
</Text>
<Text>
{bookImage}
</Text>
<Text>
{description}
</Text>
<Text>
{title}
</Text>
<Image source={{ uri: bookImage }} />
</View>;
Book.propTypes = {
author: React.PropTypes.string.isRequired,
bookImage: React.PropTypes.string.isRequired,
description: React.PropTypes.string.isRequired,
title: React.PropTypes.string.isRequired,
};
export default Book;
Sample Book Props
{
author: "Vi Keeland",
bookImage: "https://s1.nyt.com/du/books/images/9781942215462.jpg",
description: "Reese dismisses a chance encounter with a smug stranger, until he turns out to be her new boss.",
title: "BOSSMAN"
}
When using images that come from a remote location (such as your bookImage you need to set an explicit width and height on the Image's style. This is due to the fact that there is not automatic way for react-native to know how big the images is going to be.
Check the Image documentation for strategies on calculating the Image's size before being rendered. In my experience however simply setting the width and height explicitely is enough most of the times.