BotFramework-Webchat 中间件:设置 css class 名称

BotFramework-Webchat Middleware: set css class names

我想根据卡片类型将 css class 名称添加到相应的 html 元素。

我已经通过设置 [AdaptiveCard.customCssSelector] 1 属性做到了这一点。 例如。您只需要在 this line 中添加 builder.card.customCssSelector = "ac-thumbnail";,生成的 html 块将包含 class="ac-container ac-thumbnail".

但是,我想独立于 Botframework-Webchat 更新并将此逻辑放入中间件中。根据 BotFramework-Webchat docs 可以将 attachmentMiddleware 添加到 renderWebChat 函数并操作 html 元素。
事实上,我得到了活动和附件,但我无法操作 html-blocks 或添加 css 选择器。

这是我的中间件代码:

export const cardCssSelector = ({ dispatch }) => next => action => {
    if (action.type === 'DIRECT_LINE/INCOMING_ACTIVITY') {
        const { activity } = action.payload;
         for (var index in activity.attachments) {       
            const card  = activity.attachments[index].content;
            if(card.tap && card.tap.value){
                card.customCssSelector = 'tap';
            }
        }
    }
    console.log(action);
    return next(action);
};

当然这不起作用,因为附件没有 customCssSelector 属性。

要实现网络聊天的真正自定义样式,则需要一些黑客技术。一些注意事项:

  • 您需要匹配卡中传递的值,而不是 activity 中传递的值。这允许您识别 html 文档中要设置样式的特定卡片。为简单起见,我匹配按钮文本值。
  • 在网络聊天中,针对文档,卡片呈现为自适应卡片。
  • 我将 adaptiveCards [HTMLCollection] 重铸为真正的数组 (cards) 以进行迭代。
  • 我添加 card- classes 用于将 CSS 映射到卡片。
  • 因为基本自适应卡与转换后的 "hero card" 自适应卡具有相同的文档结构,我可以指望按钮是第三个 child (children[2]) 用于检索值.您需要考虑卡片的变化。
  • 对于有多张卡片的活动,您可能需要进行调整,但按照与以下类似的设置应该可以做到。

首先,创建一个商店并过滤传入的活动、消息,然后是 ac-adaptiveCard class。

const store = window.WebChat.createStore( {}, ( { dispatch } ) => next => async action => {
  if(activity.type === 'message') {
    let aCards = document.body.getElementsByClassName('ac-adaptiveCard');
    let bCards = Object.values( aCards);

    for(let i = 0; i <= bCards.length - 1; i++) {
      if( cards[i].children[2] && cards[i].children[2].innerText && cards[ i ].children[ 2 ].innerText === 'Request Assistance') {
        cards[i].className += ' card-Adaptive'
      }

      if( cards[i].children[2] && cards[i].children[2].innerText && cards[ i ].children[ 2 ].innerText === 'Service details') {
        cards[i].className += ' card-Hero'
      }
    }
  }
}

我通过指定 class 为卡片应用样式。

.card-Adaptive {
  background-color: black;
}

.card-Adaptive p {
  color: white;
}

.card-Hero {
  background-color: green;
}

我将store作为参数传递。

window.ReactDOM.render(
  <ReactWebChat
    directLine={ directLine }
    store={store}
  />,
  document.getElementById( 'webchat' )
);

自适应卡为黑色,英雄卡为绿色