diff --git a/app/client/src/assets/images/comments-onboarding/thumbnails/step-1.jpg b/app/client/src/assets/images/comments-onboarding/thumbnails/step-1.jpg new file mode 100644 index 0000000000..48d2fa141f Binary files /dev/null and b/app/client/src/assets/images/comments-onboarding/thumbnails/step-1.jpg differ diff --git a/app/client/src/assets/images/comments-onboarding/thumbnails/step-2.jpg b/app/client/src/assets/images/comments-onboarding/thumbnails/step-2.jpg new file mode 100644 index 0000000000..72c3e4cdbb Binary files /dev/null and b/app/client/src/assets/images/comments-onboarding/thumbnails/step-2.jpg differ diff --git a/app/client/src/comments/CommentCard/CommentCard.tsx b/app/client/src/comments/CommentCard/CommentCard.tsx index 96dbcb12d3..6c0d9664f6 100644 --- a/app/client/src/comments/CommentCard/CommentCard.tsx +++ b/app/client/src/comments/CommentCard/CommentCard.tsx @@ -43,6 +43,7 @@ import { deleteCommentThreadRequest, addCommentReaction, removeCommentReaction, + setVisibleThread, } from "actions/commentActions"; import { useDispatch, useSelector } from "react-redux"; import { commentThreadsSelector } from "selectors/commentsSelectors"; @@ -376,6 +377,11 @@ function CommentCard({ history.push( `${commentThreadURL.pathname}${commentThreadURL.search}${commentThreadURL.hash}`, ); + + // update visible thread to make it visible + // even if the query param is not updated + dispatch(setVisibleThread(commentThreadId)); + if (!commentThread.isViewed) { dispatch(markThreadAsReadRequest(commentThreadId)); } diff --git a/app/client/src/comments/CommentsShowcaseCarousel/CommentsCarouselModal.tsx b/app/client/src/comments/CommentsShowcaseCarousel/CommentsCarouselModal.tsx index 066d2418fc..2f361020d7 100644 --- a/app/client/src/comments/CommentsShowcaseCarousel/CommentsCarouselModal.tsx +++ b/app/client/src/comments/CommentsShowcaseCarousel/CommentsCarouselModal.tsx @@ -1,8 +1,12 @@ import React from "react"; import ModalComponent from "components/designSystems/blueprint/ModalComponent"; import { Layers } from "constants/Layers"; +import { useDispatch } from "react-redux"; +import { hideCommentsIntroCarousel } from "actions/commentActions"; function ShowcaseCarouselModal({ children }: { children: React.ReactNode }) { + const dispatch = useDispatch(); + return ( { - // TODO (rishabh) handle close + dispatch(hideCommentsIntroCarousel()); }} overlayClassName="comments-onboarding-carousel" portalClassName="comments-onboarding-carousel-portal" diff --git a/app/client/src/comments/CommentsShowcaseCarousel/index.tsx b/app/client/src/comments/CommentsShowcaseCarousel/index.tsx index 61bf723071..c5828137f1 100644 --- a/app/client/src/comments/CommentsShowcaseCarousel/index.tsx +++ b/app/client/src/comments/CommentsShowcaseCarousel/index.tsx @@ -4,6 +4,9 @@ import Text, { TextType } from "components/ads/Text"; import ShowcaseCarousel, { Steps } from "components/ads/ShowcaseCarousel"; import ProfileForm, { PROFILE_FORM } from "./ProfileForm"; import CommentsCarouselModal from "./CommentsCarouselModal"; +import ProgressiveImage, { + Container as ProgressiveImageContainer, +} from "components/ads/ProgressiveImage"; import styled, { withTheme } from "styled-components"; import { Theme } from "constants/DefaultTheme"; @@ -27,6 +30,9 @@ import { getCurrentAppOrg } from "selectors/organizationSelectors"; import useOrg from "utils/hooks/useOrg"; import { getCanManage } from "utils/helpers"; +import stepOneThumbnail from "assets/images/comments-onboarding/thumbnails/step-1.jpg"; +import stepTwoThumbnail from "assets/images/comments-onboarding/thumbnails/step-2.jpg"; + const getBanner = (step: number) => `${S3_BUCKET_URL}/comments/step-${step}.png`; @@ -36,15 +42,15 @@ const introStepsEditor = [ content: "You can now collaborate with your users to build apps faster. Invite your team to comment on your apps, exchange thoughts & ship your ideas.", banner: getBanner(1), + bannerThumbnail: stepOneThumbnail, hideBackBtn: true, - bannerProps: { style: { height: 284 } }, }, { title: "Give Contextual Feedback", content: "Drop a comment on a widget to suggest an improvement. Comments are tagged to the widget and move along with it. Update the widget and iterate your way to shipping your ideas!", banner: getBanner(2), - bannerProps: { style: { height: 284 } }, + bannerThumbnail: stepTwoThumbnail, }, ]; @@ -54,15 +60,15 @@ const introStepsViewer = [ content: "You can now collaborate with your developers to build apps faster. Exchange thoughts, leave feedback & ship your ideas.", banner: getBanner(1), + bannerThumbnail: stepOneThumbnail, hideBackBtn: true, - bannerProps: { style: { height: 284 } }, }, { title: "Give Contextual Feedback", content: "Drop a comment on a widget to suggest an improvement or report an issue. Comments are tagged to the widget, resolve them once the updates are live!", banner: getBanner(2), - bannerProps: { style: { height: 284 } }, + bannerThumbnail: stepTwoThumbnail, }, ]; @@ -70,21 +76,33 @@ const IntroContentContainer = styled.div` padding: ${(props) => props.theme.spaces[5]}px; `; -const StyledImg = styled.img` - width: 100%; - object-fit: contain; +const BannerContainer = styled.div` + & ${ProgressiveImageContainer} { + width: 100%; + height: 284px; + } + .progressive-image--thumb, + progressive-image--full { + object-fit: contain; + } `; function IntroStep(props: { title: string; content: string; banner: string; + bannerThumbnail: any; theme: Theme; bannerProps: any; }) { return ( <> - + + +
} enforceFocus={false} - hasBackdrop // isOpen is controlled so that newly created threads are set to be visible isOpen={!!isCommentThreadVisible} minimal diff --git a/app/client/src/comments/tour/commentsTourSteps.ts b/app/client/src/comments/tour/commentsTourSteps.ts index 1849f3649c..7154318afc 100644 --- a/app/client/src/comments/tour/commentsTourSteps.ts +++ b/app/client/src/comments/tour/commentsTourSteps.ts @@ -19,7 +19,7 @@ export const commentsTourStepsEditMode = [ { id: commentsTourStepsEditModeTypes.SAY_HELLO, data: { - message: "Say hello to team appsmith", + message: "type Hello", tooltipProps: { position: Position.TOP }, }, }, diff --git a/app/client/src/components/ads/DisplayImageUpload.tsx b/app/client/src/components/ads/DisplayImageUpload.tsx index b632fb502c..6e72e1d2ba 100644 --- a/app/client/src/components/ads/DisplayImageUpload.tsx +++ b/app/client/src/components/ads/DisplayImageUpload.tsx @@ -155,7 +155,6 @@ export default function DisplayImageUpload({ canOutsideClickClose className="file-picker-dialog" isOpen={isModalOpen} - maxHeight={"80vh"} trigger={
diff --git a/app/client/src/components/ads/EmojiReactions.tsx b/app/client/src/components/ads/EmojiReactions.tsx index cd57d6f64e..27139b6933 100644 --- a/app/client/src/components/ads/EmojiReactions.tsx +++ b/app/client/src/components/ads/EmojiReactions.tsx @@ -28,9 +28,11 @@ const Bubble = styled.div<{ active?: boolean }>` : "transparent"}; border-radius: ${(props) => `${props.theme.radii[4]}px`}; - margin-left: ${(props) => `${props.theme.radii[1]}px`}; - &:first-child { - margin-left: 0; + margin-right: ${(props) => `${props.theme.radii[1]}px`}; + + /* At times the rendered emoji has width as 16px */ + & span.emoji { + min-width: 20px; } `; @@ -156,7 +158,7 @@ function EmojiReactions({ active={reaction.active} onClick={(e) => handleSelectReaction(e, reaction.reactionEmoji)} > - {reaction.reactionEmoji} + {reaction.reactionEmoji} {reaction.count > 1 && ( {reaction.count} )} diff --git a/app/client/src/components/ads/ProgressiveImage.tsx b/app/client/src/components/ads/ProgressiveImage.tsx new file mode 100644 index 0000000000..709b7101a9 --- /dev/null +++ b/app/client/src/components/ads/ProgressiveImage.tsx @@ -0,0 +1,57 @@ +import React from "react"; +import { useEffect } from "react"; +import styled from "styled-components"; + +export const Container = styled.div` + position: relative; + .progressive-image { + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + } + .progressive-image--full { + transition: opacity 300ms ease 0ms; + } + .progressive-image--thumb { + filter: blur(2px); + transition: visibility 0ms ease 300ms; + } +`; + +/** + * Use a tiny blurred image (thumbnail) until the actual image is fetched + */ +function ProgressiveImage(props: { + thumbnailSource?: string; + imageSource?: string; + alt?: string; +}) { + const [isLoaded, setIsLoaded] = React.useState(false); + + useEffect(() => { + setIsLoaded(false); + }, [props.imageSource]); + + return ( + + {props.alt} + {props.alt} { + setIsLoaded(true); + }} + src={props.imageSource} + style={{ opacity: isLoaded ? 1 : 0 }} + /> + + ); +} +export default ProgressiveImage; diff --git a/app/client/src/globalStyles/uppy.ts b/app/client/src/globalStyles/uppy.ts index 86b57d3d0f..48ee00d541 100644 --- a/app/client/src/globalStyles/uppy.ts +++ b/app/client/src/globalStyles/uppy.ts @@ -8,4 +8,20 @@ export const UppyStyles = createGlobalStyle` a.uppy-Dashboard-poweredBy { display: none; } + + .bp3-dialog.file-picker-dialog { + margin: 48px 0; + } + + .cropper-view-box { + box-shadow: 0 0 0 1px #39f; + border-radius: 50%; + outline: 0; + } + .cropper-face { + background-color:inherit !important; + } + .cropper-view-box { + outline:inherit !important; + } `; diff --git a/app/client/src/pages/Editor/ToggleModeButton.tsx b/app/client/src/pages/Editor/ToggleModeButton.tsx index e92f7d93a0..7c9cdeaf80 100644 --- a/app/client/src/pages/Editor/ToggleModeButton.tsx +++ b/app/client/src/pages/Editor/ToggleModeButton.tsx @@ -150,6 +150,7 @@ const useUpdateCommentMode = async (currentUser?: User) => { if (updatedIsCommentMode && !isCommentsIntroSeen) { dispatch(showCommentsIntroCarousel()); + setCommentModeInUrl(false); } else { setCommentModeInStore(updatedIsCommentMode); } diff --git a/app/client/src/reducers/uiReducers/commentsReducer/commentsReducer.ts b/app/client/src/reducers/uiReducers/commentsReducer/commentsReducer.ts index 04910dd8f0..8dd65fadf8 100644 --- a/app/client/src/reducers/uiReducers/commentsReducer/commentsReducer.ts +++ b/app/client/src/reducers/uiReducers/commentsReducer/commentsReducer.ts @@ -74,7 +74,6 @@ const commentsReducer = createReducer(initialState, { ) => ({ ...state, isCommentMode: action.payload && state.areCommentsEnabled, - isIntroCarouselVisible: false, }), [ReduxActionTypes.CREATE_COMMENT_THREAD_REQUEST]: ( state: CommentsReduxState,