Skip to content

Commit

Permalink
feat(landing): Add new features pop up to alert users for recent rele…
Browse files Browse the repository at this point in the history
…ases. BM-1064 (#3356)

### Motivation
We want to alert Basemaps users about new features for recent release.
To use the @linzjs/lui ->
[LuiUpdatesSplashModal](https://github.com/linz/Lui/blob/master/src/components/LuiUpdateSplashModal/LuiUpdatesSplashModal.tsx)
which is same with land online search.

### Modifications
Initial investigations with @linzjs/lui that it's very hard to import
and use react components from it because different tech stacks.
- lui build and bundled with nodejs which contains dependencies like
`crypto` or `stream` that is not support by browser. We might need to do
polyfills to map them into browser friendly dependencies.
- lui only bundle everything into one index.js, we don't have individual
module file to do direct import, so we have to deal with dependency
problem above.

As a result, we decide to re-implement the `LuiUpdatesSplashModal` in
basemaps just using the assets and css from @linzjs/lui
- `FeatureUpdates` is a completely re-implementation of
`LuiUpdatesSplashModal`
- `NewFeature` is the component that we need to update often when
describe new features.
- Updated @linzjs/lui to latest

### Verification
- Tested new pop up only show once after dismissed.
- Tested new pop up stop showing after closing date.
- Tested new pop up shows in incognito mode/clearing cache after
dismissed.

![image](https://github.com/user-attachments/assets/2440883b-9b00-4bf1-bfdc-a00de6f21fc3)

![image](https://github.com/user-attachments/assets/7061711b-81a5-407c-b442-ea02ef8bf161)
  • Loading branch information
Wentao-Kuang authored Oct 10, 2024
1 parent 5b207de commit a61b652
Show file tree
Hide file tree
Showing 6 changed files with 188 additions and 5 deletions.
19 changes: 15 additions & 4 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

12 changes: 11 additions & 1 deletion packages/landing/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -33,15 +33,17 @@
"@basemaps/geo": "^7.11.0",
"@basemaps/infra": "^7.11.0",
"@basemaps/shared": "^7.11.0",
"@linzjs/lui": "^21.12.1",
"@linzjs/lui": "^21.46.0",
"@servie/events": "^3.0.0",
"@types/proj4": "^2.5.2",
"@types/react-dom": "^18.0.6",
"@types/react-modal": "^3.16.3",
"maplibre-gl": "^4.5.0",
"mime-types": "^2.1.35",
"proj4": "^2.8.0",
"react": "^18.2.0",
"react-dom": "^18.2.0",
"react-modal": "^3.16.1",
"ulid": "^2.3.0"
},
"publishConfig": {
Expand All @@ -60,6 +62,14 @@
"entry": "../../node_modules/@linzjs/lui/dist/assets/images/linz-motif.svg",
"outfile": "dist/assets/logo-linz.svg"
},
{
"entry": "../../node_modules/@linzjs/lui/dist/assets/icons/whats_new_updates.svg",
"outfile": "dist/assets/whats_new_updates.svg"
},
{
"entry": "../../node_modules/@linzjs/lui/dist/assets/icons/clear.svg",
"outfile": "dist/assets/clear.svg"
},
{
"entry": "../../node_modules/@linzjs/lui/dist/assets/fonts",
"outfile": "dist/assets/fonts"
Expand Down
107 changes: 107 additions & 0 deletions packages/landing/src/components/feature.updates.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
import { clsx } from 'clsx';
import { Component, ReactNode } from 'react';
import ReactModal from 'react-modal';

import { Config } from '../config.js';

type FeatureUpdatesProps = {
header: string;
wrapperClass?: string;
id: string;
dismissedKey: string;
closingDate: Date;
enabled: boolean;
children?: ReactNode;
} & { bigImage: string; smallImage: string; iframe?: never };

type FeatureUpdatesState = {
showModal: boolean;
};

/**
* FeatureUpdates is a re-implementation of @linzjs/lui -> LuiUpdatesSplashModal module,
* This use to enable a one off pop up screen for introduce new feature of the recent release.
*
*/
export class FeatureUpdates extends Component<FeatureUpdatesProps, FeatureUpdatesState> {
constructor(props: FeatureUpdatesProps) {
super(props);

const id = window.localStorage.getItem(this.props.id);

this.state = {
showModal: this.props.enabled && this.props.dismissedKey !== id && this.props.closingDate >= new Date(),
};
}

handleClose = (): void => {
this.setState({ showModal: false });
window.localStorage.setItem(this.props.id, this.props.dismissedKey);
};

override render(): ReactNode {
const { header, wrapperClass, children, bigImage, smallImage } = this.props;
const { showModal } = this.state;

if (!showModal) return null;
if (Config.map.isDebug) return;

return (
<ReactModal
isOpen={showModal}
shouldCloseOnEsc={true}
onRequestClose={this.handleClose}
shouldCloseOnOverlayClick={true}
contentLabel="Recent updates"
className="lui-splash-content lui-box-shadow"
overlayClassName="splash_overlay"
appElement={document.getElementById('main') || undefined}
>
<div className={clsx('lui-large-feature-notification', wrapperClass)}>
<div className="lui-feature-header">
<div className="lui-feature-title-wrapper">
{this.WhatsNewIcon()}
<h1>{header}</h1>
</div>
<button aria-label="Close dialog" onClick={this.handleClose}>
{this.ClearIcon()}
</button>
</div>
{this.FeatureImages(bigImage, smallImage)}
<div className="lui-feature-text">{children}</div>
</div>
</ReactModal>
);
}

FeatureImages(bigImage: string, smallImage: string): ReactNode {
return (
<div className="lui-feature-img">
<img className="lui-hide-xs lui-hide-sm" alt={"What's new"} src={bigImage} />
<img className="lui-hide-md lui-hide-lg lui-hide-xl" alt={"What's new"} src={smallImage} />
</div>
);
}

// @linzjs/lui whats_new_icon re-implementation
WhatsNewIcon(): ReactNode {
return (
<span
className={'LuiIcon LuiIcon--md lui-feature-title-icon '}
data-icon={'ic_whats_new_updates'}
aria-label={'whats_new_icon'}
>
<img src="assets/whats_new_updates.svg" alt="whats_new_icon" />
</span>
);
}

// @linzjs/lui cross_icon re-implementation
ClearIcon(): ReactNode {
return (
<span className="LuiIcon LuiIcon--md LuiIcon--interactive" data-icon="ic_clear" aria-label="cross_icon">
<img src="/assets/clear.svg" alt="cross_icon" />
</span>
);
}
}
49 changes: 49 additions & 0 deletions packages/landing/src/components/new-features/3d.map.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { Component, ReactNode } from 'react';

import { WindowUrl } from '../../url.js';
import { FeatureUpdates } from '../feature.updates.js';

const baseUrl = WindowUrl.baseUrl();

/**
* Please updated the following settings and descriptions for new features pop up
*/
const bigImage = new URL('assets/Lg+3D+Maps+splash.gif', baseUrl).href; // Large gif file location
const smallImage = new URL('assets/Sml+3D+map+splash.gif', baseUrl).href; // Small gif file location
const closingDate = new Date('2024-10-30'); // End date for pop up screen
const id = `LINZ_Basemaps_3D_Map`; // Optional to set as Config.Version to disable Modal as default
const dismissedKey = 'DISMISSED_MODALS_2024_10_3d_map'; // Feature released version can both been major version or minor version
const recentUpdates = {
children: (
<>
<h2>Basemaps are now viewable in 3D!</h2>
<p>
To activate this function, click the mountains icon on the left-hand side then hold right-click to change your
viewpoint.
</p>
<p>The new Labels button can also be toggled to show places names.</p>
</>
),
bigImage,
smallImage,
};

export class NewFeature extends Component {
enabled = true;

override render(): ReactNode {
return (
<FeatureUpdates
id={id}
header="What's new"
dismissedKey={dismissedKey}
closingDate={closingDate}
bigImage={recentUpdates.bigImage}
smallImage={recentUpdates.smallImage}
enabled={this.enabled}
>
{recentUpdates.children}
</FeatureUpdates>
);
}
}
2 changes: 2 additions & 0 deletions packages/landing/src/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import { createRoot } from 'react-dom/client';
import { Footer } from './components/layout.footer.js';
import { Header } from './components/layout.header.js';
import { Basemaps } from './components/map.js';
import { NewFeature } from './components/new-features/3d.map.js';
import { Config } from './config.js';
import { WindowUrl } from './url.js';
import { isWebpSupported } from './webp.js';
Expand All @@ -13,6 +14,7 @@ class Page extends Component {
return (
<Fragment>
<Header />
<NewFeature />
<Basemaps />
<Footer />
</Fragment>
Expand Down
4 changes: 4 additions & 0 deletions packages/landing/static/index.css
Original file line number Diff line number Diff line change
Expand Up @@ -257,4 +257,8 @@ have higher specifity than the default styles of the react-select component

.display-none {
display: none!important;
}

.lui-feature-img img {
padding: 20px;
}

0 comments on commit a61b652

Please sign in to comment.