Skip to content

Commit

Permalink
Handle active and complete statuses
Browse files Browse the repository at this point in the history
  • Loading branch information
OEvgeny committed Jan 10, 2025
1 parent 61210c2 commit 21c2baf
Show file tree
Hide file tree
Showing 22 changed files with 159 additions and 30 deletions.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
42 changes: 42 additions & 0 deletions __tests__/html/fluentTheme/side-by-side.wide.dark.html
Original file line number Diff line number Diff line change
Expand Up @@ -613,6 +613,48 @@
$ pip install numpy matplotlib`
}
], [
{
from:{
role: "bot"
},
id: "a-00000",
type: "message",
text: "This is compleded feedback action example.",
timestamp: timestamp(),
entities: [
{
...aiMessageEntity,
keywords: ['AIGeneratedContent', 'AllowCopy'],
potentialAction: [
{
"@type": "LikeAction",
actionStatus: "CompletedActionStatus",
target: {
"@type": "EntryPoint",
urlTemplate: "ms-directline://postback?interaction=like"
}
},
{
"@type": "DislikeAction",
actionStatus: "PotentialActionStatus",
result: {
"@type": "Review",
reviewBody: "I don't like it.",
"reviewBody-input": {
"@type": "PropertyValueSpecification",
valueMinLength: 3,
valueName: "reason"
}
},
target: {
"@type": "EntryPoint",
urlTemplate: "ms-directline://postback?interaction=dislike{&reason}"
}
}
]
}
]
},
{
from:{
role: "bot"
Expand Down
42 changes: 42 additions & 0 deletions __tests__/html/fluentTheme/side-by-side.wide.html
Original file line number Diff line number Diff line change
Expand Up @@ -623,6 +623,48 @@
$ pip install numpy matplotlib`
}
], [
{
from:{
role: "bot"
},
id: "a-00000",
type: "message",
text: "This is compleded feedback action example.",
timestamp: timestamp(),
entities: [
{
...aiMessageEntity,
keywords: ['AIGeneratedContent', 'AllowCopy'],
potentialAction: [
{
"@type": "LikeAction",
actionStatus: "CompletedActionStatus",
target: {
"@type": "EntryPoint",
urlTemplate: "ms-directline://postback?interaction=like"
}
},
{
"@type": "DislikeAction",
actionStatus: "PotentialActionStatus",
result: {
"@type": "Review",
reviewBody: "I don't like it.",
"reviewBody-input": {
"@type": "PropertyValueSpecification",
valueMinLength: 3,
valueName: "reason"
}
},
target: {
"@type": "EntryPoint",
urlTemplate: "ms-directline://postback?interaction=dislike{&reason}"
}
}
]
}
]
},
{
from:{
role: "bot"
Expand Down
4 changes: 3 additions & 1 deletion packages/api/src/localization/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -172,8 +172,10 @@
"_TYPING_INDICATOR_MULTIPLE_TEXT.comment": "This shows when two or more users are typing simultaneously.",
"TYPING_INDICATOR_MULTIPLE_TEXT": "$1 and others are typing.",
"VIEW_CODE_BUTTON_TEXT": "Code",
"VOTE_COMPLETE_ALT": "Feedback recorded",
"VOTE_COMPLETE_ALT.comment": "This is for screen reader. The label of a button with a thumb up/down icons. The label is placed when feedback was recorded.",
"VOTE_DISLIKE_ALT": "Dislike",
"_VOTE_DISLIKE_ALT.comment": "This is for screen reader. The label of a button with a thumb up icon and is placed next to the timestamp. The button is for giving feedback that the end-user don't think the response is useful.",
"_VOTE_DISLIKE_ALT.comment": "This is for screen reader. The label of a button with a thumb up icon. The button is for giving feedback that the end-user don't think the response is useful.",
"VOTE_LIKE_ALT": "Like",
"_VOTE_LIKE_ALT.comment": "This is for screen reader. The label of a button with a thumb up icon and is placed next to the timestamp. The button is for giving feedback that the end-user think the response is useful."
}
23 changes: 20 additions & 3 deletions packages/component/src/Activity/private/Feedback.tsx
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
import { hooks } from 'botframework-webchat-api';
import { type OrgSchemaAction } from 'botframework-webchat-core';
import React, { Fragment, memo, useEffect, useState, type PropsWithChildren } from 'react';
import React, { Fragment, memo, useEffect, useMemo, useState, type PropsWithChildren } from 'react';
import { useRefFrom } from 'use-ref-from';

import FeedbackVoteButton from './VoteButton';

const { usePonyfill, usePostActivity } = hooks;
const { usePonyfill, usePostActivity, useLocalizer } = hooks;

type Props = Readonly<
PropsWithChildren<{
Expand All @@ -20,6 +20,7 @@ const Feedback = memo(({ actions, className }: Props) => {
const [{ clearTimeout, setTimeout }] = usePonyfill();
const [selectedAction, setSelectedAction] = useState<OrgSchemaAction | undefined>();
const postActivity = usePostActivity();
const localize = useLocalizer();

const postActivityRef = useRefFrom(postActivity);

Expand All @@ -42,6 +43,17 @@ const Feedback = memo(({ actions, className }: Props) => {
return () => clearTimeout(timeout);
}, [clearTimeout, postActivityRef, selectedAction, setTimeout]);

const actionProps = useMemo(
() =>
[...actions].some(action => action.actionStatus === 'CompletedActionStatus')
? {
title: localize('VOTE_COMPLETE_ALT'),
disabled: true
}
: undefined,
[actions, localize]
);

return (
<Fragment>
{Array.from(actions).map((action, index) => (
Expand All @@ -50,7 +62,12 @@ const Feedback = memo(({ actions, className }: Props) => {
className={className}
key={action['@id'] || index}
onClick={setSelectedAction}
pressed={selectedAction === action}
pressed={
selectedAction === action ||
action.actionStatus === 'CompletedActionStatus' ||
action.actionStatus === 'ActiveActionStatus'
}
{...actionProps}
/>
))}
</Fragment>
Expand Down
24 changes: 17 additions & 7 deletions packages/component/src/Activity/private/ThumbButton.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { hooks } from 'botframework-webchat-api';
import classNames from 'classnames';
import React, { memo } from 'react';
import React, { memo, useCallback, useMemo } from 'react';
import { useRefFrom } from 'use-ref-from';

import ThumbButtonImage from './ThumbButton.Image';
import useStyleSet from '../../hooks/useStyleSet';
Expand All @@ -10,32 +11,41 @@ const { useLocalizer } = hooks;
type Props = Readonly<{
className?: string | undefined;
direction: 'down' | 'up';
disabled?: boolean | undefined;
onClick?: () => void;
pressed?: boolean;
title?: string | undefined;
}>;

const ThumbButton = memo(({ className, direction, onClick, pressed }: Props) => {
const ThumbButton = memo(({ className, direction, disabled, onClick, pressed, title }: Props) => {
const [{ thumbButton }] = useStyleSet();
const localize = useLocalizer();
const onClickRef = useRefFrom(onClick);

const title = localize(direction === 'down' ? 'VOTE_DISLIKE_ALT' : 'VOTE_LIKE_ALT');
const buttonTitle = useMemo(
() => title ?? localize(direction === 'down' ? 'VOTE_DISLIKE_ALT' : 'VOTE_LIKE_ALT'),
[direction, localize, title]
);

const handleClick = useCallback(() => !disabled && onClickRef.current?.(), [disabled, onClickRef]);

return (
<button
aria-label={title}
aria-disabled={disabled ? 'true' : undefined}
aria-label={buttonTitle}
aria-pressed={pressed}
className={classNames(
'webchat__thumb-button',
{ 'webchat__thumb-button--is-pressed': pressed },
className,
thumbButton + ''
)}
onClick={onClick}
title={title}
onClick={handleClick}
title={buttonTitle}
type="button"
>
<ThumbButtonImage
className={classNames('webchat__thumb-button__image', {
className={classNames('webchat__thumb-button__image', 'webchat__thumb-button__image--is-stroked', {
'webchat__thumb-button__image--is-down': direction === 'down'
})}
direction={direction}
Expand Down
11 changes: 6 additions & 5 deletions packages/component/src/Activity/private/VoteButton.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import { onErrorResumeNext, parseVoteAction, type OrgSchemaAction } from 'botframework-webchat-core';
import cx from 'classnames';
import React, { memo, useCallback, useMemo } from 'react';
import { useRefFrom } from 'use-ref-from';

Expand All @@ -8,11 +7,13 @@ import ThumbsButton from './ThumbButton';
type Props = Readonly<{
className?: string | undefined;
action: OrgSchemaAction;
disabled?: boolean | undefined;
onClick?: (action: OrgSchemaAction) => void;
pressed: boolean;
title?: string | undefined;
}>;

const FeedbackVoteButton = memo(({ action, className, onClick, pressed }: Props) => {
const FeedbackVoteButton = memo(({ action, className, disabled, onClick, pressed, title }: Props) => {
const onClickRef = useRefFrom(onClick);
const voteActionRef = useRefFrom(action);

Expand All @@ -32,12 +33,12 @@ const FeedbackVoteButton = memo(({ action, className, onClick, pressed }: Props)

return (
<ThumbsButton
className={cx(className, {
'webchat__thumb-button--is-complete': action.actionStatus === 'CompletedActionStatus'
})}
className={className}
direction={direction}
disabled={disabled}
onClick={handleClick}
pressed={pressed}
title={title}
/>
);
});
Expand Down
41 changes: 28 additions & 13 deletions packages/component/src/Styles/StyleSet/ThumbButton.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,25 +3,26 @@ import CSSTokens from '../CSSTokens';
export default function () {
return {
'&.webchat__thumb-button': {
alignItems: 'center',
appearance: 'none',
background: 'transparent',
border: 0,
borderRadius: 2,
boxSizing: 'content-box',
display: 'grid',
gridTemplateAreas: `"icon"`,
height: 16,
justifyContent: 'center',
/* The Fluent icon is larger than the button. We need to clip it.
Without clipping, hover effect will appear on the edge of the button but not possible to click. */
overflow: ['hidden', 'clip'],
padding: 0,
width: 16,

'&.webchat__thumb-button--large': {
alignItems: 'center',
border: '1px solid transparent',
borderRadius: '4px',
display: 'flex',
height: '20px',
justifyContent: 'center',
padding: '5px',
width: '20px',

Expand All @@ -35,6 +36,10 @@ export default function () {
'&:hover, &:active, &.webchat__thumb-button--is-pressed': {
background: 'transparent',
color: CSSTokens.ColorAccent
},

'&[aria-disabled="true"]': {
color: CSSTokens.ColorSubtle
}
},

Expand All @@ -48,22 +53,32 @@ export default function () {

'& .webchat__thumb-button__image': {
color: CSSTokens.ColorAccent,
width: 14
},
gridArea: 'icon',
visibility: 'hidden',
width: 14,

'&:hover .webchat__thumb-button__image:not(.webchat__thumb-button__image--is-filled)': {
display: 'none'
'&.webchat__thumb-button__image--is-stroked': {
visibility: 'visible'
}
},

'&.webchat__thumb-button--is-pressed .webchat__thumb-button__image:not(.webchat__thumb-button__image--is-filled)':
{
display: 'none'
'&:not([aria-disabled="true"]):hover .webchat__thumb-button__image': {
'&.webchat__thumb-button__image--is-stroked': {
visibility: 'hidden'
},
'&.webchat__thumb-button__image--is-filled': {
visibility: 'visible'
}
},

'&.webchat__thumb-button:not(:hover):not(.webchat__thumb-button--is-pressed) .webchat__thumb-button__image--is-filled':
{
display: 'none'
'&.webchat__thumb-button--is-pressed .webchat__thumb-button__image': {
'&.webchat__thumb-button__image--is-stroked': {
visibility: 'hidden'
},
'&.webchat__thumb-button__image--is-filled': {
visibility: 'visible'
}
}
}
};
}
Original file line number Diff line number Diff line change
Expand Up @@ -599,7 +599,7 @@
outline: var(--webchat-strokeWidthThick) solid var(--webchat-colorStrokeFocus2);
}

&:global(.webchat__thumb-button--is-complete) {
&[aria-disabled='true'] {
color: var(--webchat-colorNeutralForegroundDisabled);
}
}

0 comments on commit 21c2baf

Please sign in to comment.