1
Fork 0

Add the beginnings of the account settings tour.

Also added an error tour for displaying error messages when starting
a tour and a TourRequirements object.
This commit is contained in:
Bauke 2023-07-01 15:46:23 +02:00
parent 48742a9864
commit 896895c69a
Signed by: Bauke
GPG Key ID: C1C0F29952BCF558
8 changed files with 131 additions and 9 deletions

View File

@ -4,7 +4,7 @@ import {
createIntroductionUnderstood, createIntroductionUnderstood,
} from "../storage/common.js"; } from "../storage/common.js";
import {introductionSteps} from "../tours/introduction.js"; import {introductionSteps} from "../tours/introduction.js";
import {TourId, tourIdsAndSteps} from "../tours/exports.js"; import {TourId, showTourError, tourIdsAndSteps} from "../tours/exports.js";
/** The main entry point for the content script. */ /** The main entry point for the content script. */
async function main(): Promise<void> { async function main(): Promise<void> {
@ -38,10 +38,28 @@ async function main(): Promise<void> {
return; return;
} }
const userIsLoggedIn =
document.querySelector(".logged-in-user-username") !== null;
// Then run through all of the tours we have and start the first match for the // Then run through all of the tours we have and start the first match for the
// ID. // ID.
for (const [id, steps, eventHandlers] of tourIdsAndSteps) { for (const [id, steps, eventHandlers, requirements] of tourIdsAndSteps) {
if (anchorTourId === id) { if (anchorTourId === id) {
if (requirements.mustBeLoggedIn && !userIsLoggedIn) {
showTourError(
`The ${id} tour can only be shown with a logged in account.`,
);
return;
}
if (requirements.path !== window.location.pathname) {
// This tour's path requirement does not match.
showTourError(
`The ${id} tour can only be start on the ${requirements.path} page.`,
);
return;
}
startTour(id, steps, eventHandlers, false); startTour(id, steps, eventHandlers, false);
return; return;
} }

View File

@ -25,6 +25,14 @@ function tourDescription(tourId: Props["tourId"]): JSX.Element {
); );
} }
if (tourId === TourId.InterfaceAccountSettings) {
return (
<p class="tour-description">
View your account settings and all that you can customize.
</p>
);
}
return ( return (
<p class="tour-description"> <p class="tour-description">
Tour ID "{tourId}" does not have a description, this should probably be Tour ID "{tourId}" does not have a description, this should probably be
@ -45,7 +53,14 @@ function tourLink(tourId: Props["tourId"]): string {
break; break;
} }
default: case TourId.InterfaceAccountSettings: {
path = "/settings";
break;
}
default: {
throw new Error(`Unswitched tour ID: ${tourId as string}`);
}
} }
return `${baseUrl}${path}${anchor}`; return `${baseUrl}${path}${anchor}`;

View File

@ -37,6 +37,7 @@ export class Tours extends Component<Props, State> {
const tourProps: Array<Tour["props"]> = [ const tourProps: Array<Tour["props"]> = [
createTour(TourId.Introduction, "Introduction"), createTour(TourId.Introduction, "Introduction"),
createTour(TourId.InterfaceHomepage, "The Homepage"), createTour(TourId.InterfaceHomepage, "The Homepage"),
createTour(TourId.InterfaceAccountSettings, "Your Account Settings"),
]; ];
return ( return (

View File

@ -1,14 +1,54 @@
import {homepageEventHandlers, homepageSteps} from "./interface/exports.js"; import {
accountSettingsEventHandlers,
accountSettingsSteps,
homepageEventHandlers,
homepageSteps,
} from "./interface/exports.js";
import {introductionSteps} from "./introduction.js"; import {introductionSteps} from "./introduction.js";
export * from "./shared/exports.js";
export enum TourId { export enum TourId {
InterfaceAccountSettings = "interface-account-settings",
InterfaceHomepage = "interface-homepage", InterfaceHomepage = "interface-homepage",
Introduction = "introduction", Introduction = "introduction",
} }
export const tourIdsAndSteps: Array< export type TourRequirement = {
[TourId, TourStepOptions[], TourStepEventHandler[]] mustBeLoggedIn: boolean;
> = [ path: string;
[TourId.Introduction, introductionSteps, []], };
[TourId.InterfaceHomepage, homepageSteps, homepageEventHandlers],
export type TourIdsAndSteps = Array<
[TourId, TourStepOptions[], TourStepEventHandler[], TourRequirement]
>;
export const tourIdsAndSteps: TourIdsAndSteps = [
[
TourId.Introduction,
introductionSteps,
[],
{
mustBeLoggedIn: false,
path: "/",
},
],
[
TourId.InterfaceAccountSettings,
accountSettingsSteps,
accountSettingsEventHandlers,
{
mustBeLoggedIn: true,
path: "/settings",
},
],
[
TourId.InterfaceHomepage,
homepageSteps,
homepageEventHandlers,
{
mustBeLoggedIn: false,
path: "/",
},
],
]; ];

View File

@ -0,0 +1,17 @@
import type Shepherd from "shepherd.js";
import {renderInContainer} from "../utilities.js";
const step01 = renderInContainer(
<>
<h1>Your Account Settings</h1>
</>,
);
export const steps: Shepherd.Step.StepOptions[] = [
{
id: "account-settings-01",
text: step01,
},
];
export const eventHandlers: TourStepEventHandler[] = [];

View File

@ -1,3 +1,7 @@
export {
eventHandlers as accountSettingsEventHandlers,
steps as accountSettingsSteps,
} from "./account-settings.js";
export { export {
eventHandlers as homepageEventHandlers, eventHandlers as homepageEventHandlers,
steps as homepageSteps, steps as homepageSteps,

View File

@ -1 +1,2 @@
export * from "./logged-out-warning.js"; export * from "./logged-out-warning.js";
export * from "./tour-error.js";

View File

@ -0,0 +1,26 @@
import Shepherd from "shepherd.js";
import {type TourId} from "../exports.js";
import {renderInContainer} from "../utilities.js";
export function showTourError(text: string) {
const tour = new Shepherd.Tour({
defaultStepOptions: {
buttons: [
{
classes: "btn",
text: "Continue",
action() {
this.complete();
},
},
],
},
useModalOverlay: true,
});
tour.addStep({
text: renderInContainer(<p class="tish-warning">{text}</p>),
});
tour.start();
}