Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Submit intro tour #1571

Merged
merged 5 commits into from
Mar 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/common/components/community-selector/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,7 @@ export class CommunitySelector extends BaseComponent<Props, State> {
<>
<a
href="#"
id="community-picker"
className="community-selector"
onClick={(e) => {
e.preventDefault();
Expand Down
6 changes: 5 additions & 1 deletion src/common/components/editor-toolbar/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -291,7 +291,11 @@ export function EditorToolbar({

return (
<>
<div className={_c(`editor-toolbar ${sm ? "toolbar-sm" : ""}`)} ref={rootRef}>
<div
id="editor-toolbar"
className={_c(`editor-toolbar ${sm ? "toolbar-sm" : ""}`)}
ref={rootRef}
>
<Tooltip content={_t("editor-toolbar.bold")}>
<div className="editor-tool" onClick={bold}>
{formatBoldSvg}
Expand Down
5 changes: 4 additions & 1 deletion src/common/components/tag-selector/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -195,7 +195,10 @@ export class TagSelector extends Component<Props, State> {

return (
<>
<div className={_c(`tag-selector ${tags.length > 0 ? "has-tags" : ""}`)}>
<div
id="submit-tags-selector"
className={_c(`tag-selector ${tags.length > 0 ? "has-tags" : ""}`)}
>
<SuggestionList
renderer={(x: string) => {
return (
Expand Down
10 changes: 9 additions & 1 deletion src/common/features/ui/core/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import React, { createContext, PropsWithChildren } from "react";
import { useSet } from "react-use";

export * from "./intro-step.interface";

export const UIContext = createContext<{
openPopovers: Set<string>;
addOpenPopover: (v: string) => void;
Expand All @@ -17,7 +19,13 @@ export function UIManager({ children }: PropsWithChildren<unknown>) {
);

return (
<UIContext.Provider value={{ openPopovers, addOpenPopover, removeOpenPopover }}>
<UIContext.Provider
value={{
openPopovers,
addOpenPopover,
removeOpenPopover
}}
>
{children}
</UIContext.Provider>
);
Expand Down
5 changes: 5 additions & 0 deletions src/common/features/ui/core/intro-step.interface.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export interface IntroStep {
title: string;
message: string;
targetSelector: string;
}
1 change: 1 addition & 0 deletions src/common/features/ui/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,3 +10,4 @@ export * from "./alert";
export * from "./badge";
export * from "./pagination";
export * from "./core";
export * from "./intro-tour";
4 changes: 4 additions & 0 deletions src/common/features/ui/intro-tour/index.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
.intro-tour-focused {
//z-index: 1041 !important;
position: relative !important;
}
154 changes: 154 additions & 0 deletions src/common/features/ui/intro-tour/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
import React, { useEffect, useMemo, useState } from "react";
import { IntroStep } from "@ui/core";
import { useMountedState } from "react-use";
import { usePopper } from "react-popper";
import { createPortal } from "react-dom";
import { classNameObject } from "../../../helper/class-name-object";
import { Button } from "@ui/button";
import useLocalStorage from "react-use/lib/useLocalStorage";
import { PREFIX } from "../../../util/local-storage";
import "./index.scss";
import { DOMRect } from "sortablejs";

interface Props {
steps: IntroStep[];
id: string;
enabled: boolean;
forceActivation: boolean;
setForceActivation: (v: boolean) => void;
}

export function IntroTour({ steps, id, enabled, forceActivation, setForceActivation }: Props) {
const [currentStep, setCurrentStep, clearCurrentStep] = useLocalStorage<number | undefined>(
PREFIX + `_it_${id}`,
undefined
);
const [isFinished, setIsFinished] = useLocalStorage(PREFIX + `_itf_${id}`, false);

const [host, setHost] = useState<any>();
const [popperElement, setPopperElement] = useState<any>();
const [hostRect, setHostRect] = useState<DOMRect>();

const isMounted = useMountedState();
const popper = usePopper(host, popperElement, {
placement: "top"
});

const step = useMemo(
() => (typeof currentStep === "number" ? steps[currentStep] : undefined),
[currentStep, steps]
);
const totalSteps = useMemo(() => steps.length, [steps]);
const isFirstStep = useMemo(
() => typeof currentStep === "number" && currentStep > 0,
[currentStep]
);
const isLastStep = useMemo(() => steps.length - 1 === currentStep, [steps, currentStep]);
const clipPath = useMemo(
() =>
hostRect
? `polygon(0% 0%, 0% 100%, ${hostRect.x}px 100%, ${hostRect.x}px ${hostRect.y}px, ${
hostRect.x + hostRect.width
}px ${hostRect.y}px, ${hostRect.x + hostRect.width}px ${
hostRect.y + hostRect.height
}px, ${hostRect.x}px ${hostRect.y + hostRect.height}px, ${
hostRect.x
}px 100%, 100% 100%, 100% 0%)`
: "unset",
[hostRect]
);

// Detect enablement and set default step if there aren't any persistent step
useEffect(() => {
if (typeof currentStep === "undefined" && !isFinished && enabled) {
setCurrentStep(0);
}
}, [currentStep, enabled, isFinished]);

useEffect(() => {
if (forceActivation) {
setCurrentStep(0);
setIsFinished(false);

setForceActivation(false);
}
}, [forceActivation]);

// Re-attach host element based on host element
useEffect(() => {
host?.classList.remove("intro-tour-focused");

if (step) {
const nextHost = document.querySelector(step.targetSelector);
setHost(nextHost);

if (nextHost) {
setHostRect(nextHost.getBoundingClientRect());
nextHost.classList.add("intro-tour-focused");
}
} else {
setHost(null);
}
}, [step]);

const nextStep = () => {
if (typeof currentStep === "number" && currentStep < totalSteps - 1) {
setCurrentStep(currentStep + 1);
}
};

const prevStep = () => {
if (typeof currentStep === "number" && currentStep > 0) {
setCurrentStep(currentStep - 1);
}
};

const finish = () => {
clearCurrentStep();
setIsFinished(true);
};

return isMounted() && !isFinished ? (
<>
{createPortal(
<div
className={classNameObject({
"bg-black opacity-[50%] z-[1040] fixed top-0 left-0 right-0 bottom-0": true
})}
style={{ clipPath }}
onClick={() => finish()}
/>,
document.querySelector("#modal-overlay-container")!!
)}
{step &&
createPortal(
<div
className="p-3 border border-[--border-color] bg-white rounded-2xl flex flex-col gap-4 z-[1041] min-w-[200px] max-w-[400px]"
style={popper.styles.popper}
{...popper.attributes.popper}
ref={setPopperElement}
>
<div className="text-blue-dark-sky text-sm uppercase flex justify-between">
<span className="text-xs text-gray-600 mr-3">
{currentStep! + 1} of {steps.length}
</span>
{step?.title}
</div>
<div>{step?.message}</div>
<div className="flex justify-end gap-2 border-t border-[--border-color] pt-3">
{isFirstStep && (
<Button onClick={() => prevStep()} outline={true}>
Previous
</Button>
)}
{!isLastStep && <Button onClick={() => nextStep()}>Next</Button>}
{isLastStep && <Button onClick={() => finish()}>Finish</Button>}
</div>
</div>,
document.querySelector("#popper-container")!!
)}
</>
) : (
<></>
);
}
11 changes: 11 additions & 0 deletions src/common/i18n/locales/en-US.json
Original file line number Diff line number Diff line change
Expand Up @@ -1436,6 +1436,7 @@
"title-placeholder": "Title",
"body-placeholder": "Tell your story...",
"reward": "Reward",
"take-tour": "Take a tour",
"reward-hint": "Set author reward ratio for liquid and staked tokens",
"reward-default": "Default 50% / 50%",
"reward-sp": "Power Up 100%",
Expand Down Expand Up @@ -2383,5 +2384,15 @@
"title": "Boost+",
"sub-title": "Boost your account using Ecency points",
"already-boosted-account": "This account boosted already"
},
"submit-tour": {
"title": "Post creating",
"title-hint": "You may to set any title for your post",
"tags-hint": "Tags helps to find out your post by special keywords",
"body-hint": "Post body is rich text which may contain various of different components, styles",
"community-hint": "Post may be attached to specific community which helps to promote your post within community members",
"toolbar-hint": "Toolbar allow to insert a lot of different components, apply formatting, insert images, videos and links",
"advanced-hint": "Configure advanced settings such as scheduling, beneficiaries",
"help-hint": "Have any questions? Check out help center"
}
}
4 changes: 2 additions & 2 deletions src/common/pages/submit/_index.scss
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,9 @@
background: transparent;
border: none;

&:focus {
&:focus, &.intro-tour-focused {
@include themify(day) {
background: lighten($yellow, 46);
@apply bg-warning-046;
}

@include themify(night) {
Expand Down
Loading