Skip to content

Commit f484e1f

Browse files
committed
fix: make tile loading indicator more explicit
Signed-off-by: Ihor Dykhta <dikhta.igor@gmail.com>
1 parent e5b7df1 commit f484e1f

4 files changed

Lines changed: 81 additions & 14 deletions

File tree

src/components/src/loading-indicator.tsx

Lines changed: 50 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -2,28 +2,48 @@
22
// Copyright contributors to the kepler.gl project
33

44
import React, {PropsWithChildren} from 'react';
5-
import styled, {withTheme} from 'styled-components';
5+
import styled, {withTheme, keyframes} from 'styled-components';
66

7-
import {getNumRasterTilesBeingLoaded} from '@kepler.gl/layers';
7+
import {getNumRasterTilesBeingLoaded, getNumVectorTilesBeingLoaded} from '@kepler.gl/layers';
88

99
type StyledContainerProps = {
1010
$isVisible?: boolean;
1111
$left: number;
1212
};
1313

14+
const spin = keyframes`
15+
0% { transform: rotate(0deg); }
16+
100% { transform: rotate(360deg); }
17+
`;
18+
19+
const Spinner = styled.div`
20+
display: inline-block;
21+
width: 14px;
22+
height: 14px;
23+
margin-right: 8px;
24+
border: 2px solid ${props => props.theme.textColorHl};
25+
border-top-color: transparent;
26+
border-radius: 50%;
27+
animation: ${spin} 0.8s linear infinite;
28+
vertical-align: middle;
29+
`;
30+
1431
export const StyledContainer = styled.div<StyledContainerProps>`
1532
position: absolute;
1633
left: ${props => props.$left}px;
1734
bottom: ${props => props.theme.sidePanel.margin.left}px;
18-
z-index: 1;
19-
color: ${props => props.theme.textColorHl};
35+
z-index: 1000;
36+
color: ${props => props.theme.textColor};
2037
opacity: ${props => (props.$isVisible ? 1 : 0)};
2138
transition: opacity 0.5s ease-in-out;
2239
background-color: ${props => props.theme.sidePanelBg};
23-
border-radius: 0px;
24-
padding-left: 3px;
25-
padding-right: 3px;
26-
font-size: 12px;
40+
padding: 8px 12px;
41+
font-size: 13px;
42+
font-weight: 500;
43+
box-shadow: 0 2px 8px rgba(0, 0, 0, 0.3);
44+
backdrop-filter: blur(4px);
45+
display: flex;
46+
align-items: center;
2747
`;
2848

2949
type LoadingIndicatorProps = {
@@ -45,18 +65,37 @@ const LoadingIndicator: React.FC<LoadingIndicatorProps & {theme: any}> = ({
4565
(activeSidePanel ? (sidePanelWidth || 0) + LEFT_POSITION_ADJUSTMENT : 0) +
4666
theme.sidePanel.margin.left;
4767

48-
// Helper message to track number of raster tiles that are being loaded
68+
// Helper message to track number of tiles that are being loaded
4969
const numRasterTilesInProgress = getNumRasterTilesBeingLoaded();
50-
const extraMessage =
70+
const numVectorTilesInProgress = getNumVectorTilesBeingLoaded();
71+
72+
const rasterMessage =
5173
numRasterTilesInProgress < 1
5274
? ''
5375
: `${numRasterTilesInProgress} raster tile${
5476
numRasterTilesInProgress === 1 ? ' is' : 's are'
5577
} being loaded`;
5678

79+
const vectorMessage =
80+
numVectorTilesInProgress < 1
81+
? ''
82+
: `${numVectorTilesInProgress} vector tile${
83+
numVectorTilesInProgress === 1 ? ' is' : 's are'
84+
} being loaded`;
85+
86+
let extraMessage = '';
87+
if (rasterMessage && vectorMessage) {
88+
extraMessage = `${rasterMessage.replace(' being loaded', '')} and ${vectorMessage}`;
89+
} else if (rasterMessage) {
90+
extraMessage = rasterMessage;
91+
} else if (vectorMessage) {
92+
extraMessage = vectorMessage;
93+
}
94+
5795
return (
5896
<StyledContainer $isVisible={isVisible} $left={left}>
59-
{`Loading... ${extraMessage}`}
97+
<Spinner />
98+
<span>{`Loading... ${extraMessage}`}</span>
6099
</StyledContainer>
61100
);
62101
};

src/layers/src/index.ts

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,10 @@ export {default as AggregationLayer} from './aggregation-layer';
4343
import {default as VectorTileLayer} from './vector-tile/vector-tile-layer';
4444

4545
export {default as VectorTileIcon} from './vector-tile/vector-tile-icon';
46-
export {default as VectorTileLayer} from './vector-tile/vector-tile-layer';
46+
export {
47+
default as VectorTileLayer,
48+
getNumVectorTilesBeingLoaded
49+
} from './vector-tile/vector-tile-layer';
4750

4851
import {default as RasterTileLayer} from './raster-tile/raster-tile-layer';
4952
export {default as RasterTileIcon} from './raster-tile/raster-tile-icon';

src/layers/src/vector-tile/mvt-layer.ts

Lines changed: 11 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import {
1010
_TileLoadProps,
1111
_Tile2DHeader
1212
} from '@deck.gl/geo-layers/typed';
13+
import {incrementVectorTileLoading, decrementVectorTileLoading} from './vector-tile-layer';
1314

1415
/*
1516
Custom MVT layer that works with MVTSource and PMTileSource.
@@ -22,14 +23,22 @@ import {
2223

2324
// @ts-expect-error need to patch private methods because of newer loaders.gl
2425
export class MVTLayer<ExtraProps> extends _MVTLayer<ExtraProps> {
25-
getTileData(tile: _TileLoadProps): any {
26+
async getTileData(tile: _TileLoadProps): Promise<any> {
2627
const {getTileData} = this.props;
2728
const {data} = this.state;
2829

2930
tile.url =
3031
typeof data === 'string' || Array.isArray(data) ? _getURLFromTemplate(data, tile) : null;
3132
if (getTileData) {
32-
return getTileData(tile);
33+
incrementVectorTileLoading();
34+
try {
35+
const result = await getTileData(tile);
36+
decrementVectorTileLoading();
37+
return result;
38+
} catch (error) {
39+
decrementVectorTileLoading();
40+
throw error;
41+
}
3342
}
3443
return null;
3544
}

src/layers/src/vector-tile/vector-tile-layer.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,22 @@ import {
7070
getPropertyByZoom
7171
} from './common-tile/tile-utils';
7272

73+
// Global counter that represents the number of tiles currently being loaded across all the vector tile layers
74+
let vectorTilesBeingLoaded = 0;
75+
76+
// This is a temp solution to track loading
77+
export const getNumVectorTilesBeingLoaded = () => {
78+
return vectorTilesBeingLoaded;
79+
};
80+
81+
export const incrementVectorTileLoading = () => {
82+
vectorTilesBeingLoaded++;
83+
};
84+
85+
export const decrementVectorTileLoading = () => {
86+
vectorTilesBeingLoaded--;
87+
};
88+
7389
export const DEFAULT_HIGHLIGHT_FILL_COLOR = [252, 242, 26, 150];
7490
export const DEFAULT_HIGHLIGHT_STROKE_COLOR = [252, 242, 26, 255];
7591
export const MAX_CACHE_SIZE_MOBILE = 1; // Minimize caching, visible tiles will always be loaded

0 commit comments

Comments
 (0)