Some jsdocs
This commit is contained in:
parent
f4481a1d6c
commit
0a1842f77d
@ -21,6 +21,9 @@ import {watch} from "@vue/runtime-core";
|
||||
|
||||
import "@/assets/icons/chat.svg";
|
||||
|
||||
/**
|
||||
* Leaflet map control providing a chat button which opens the chatbox on click
|
||||
*/
|
||||
export class ChatControl extends Control {
|
||||
declare options: ControlOptions
|
||||
|
||||
|
@ -37,6 +37,9 @@ export interface ClockControlOptions extends ControlOptions {
|
||||
showWeather: boolean;
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaflet map control providing a clock which can display the current in-game time of day and weather
|
||||
*/
|
||||
export class ClockControl extends Control {
|
||||
declare options: ClockControlOptions;
|
||||
declare _container?: HTMLElement;
|
||||
|
@ -30,6 +30,9 @@ export interface CoordinatesControlOptions extends ControlOptions {
|
||||
label: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaflet map control which displays in-game block coordinates when hovering over or tapping the map
|
||||
*/
|
||||
export class CoordinatesControl extends Control {
|
||||
declare options: CoordinatesControlOptions;
|
||||
declare _map ?: Map;
|
||||
|
@ -24,6 +24,9 @@ import { toClipboard } from '@soerenmartius/vue3-clipboard';
|
||||
import {notify} from "@kyvg/vue3-notification";
|
||||
import {computed} from "@vue/runtime-core";
|
||||
|
||||
/**
|
||||
* Leaflet map control providing a button for copying a link for the current map view to the clipboard
|
||||
*/
|
||||
export class LinkControl extends Control {
|
||||
declare options: ControlOptions
|
||||
|
||||
|
@ -30,6 +30,10 @@ import LayersOptions = Control.LayersOptions;
|
||||
|
||||
const store = useStore();
|
||||
|
||||
/**
|
||||
* Extension of leaflet's standard {@link Control.Layers}
|
||||
* Sorts layers by position, adds additional keyboard navigation, adjusts to viewport size and tracks expanded state in vuex
|
||||
*/
|
||||
export class LiveAtlasLayerControl extends Control.Layers {
|
||||
declare _map ?: LeafletMap;
|
||||
declare _overlaysList?: HTMLElement;
|
||||
|
@ -37,6 +37,9 @@ export interface LoadingControlOptions extends ControlOptions {
|
||||
delayIndicator?: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaflet map control which displays a loading spinner when any tiles are loading
|
||||
*/
|
||||
export class LoadingControl extends Control {
|
||||
declare options: LoadingControlOptions;
|
||||
|
||||
|
@ -26,6 +26,9 @@ import {ActionTypes} from "@/store/action-types";
|
||||
import {notify} from "@kyvg/vue3-notification";
|
||||
import LiveAtlasLeafletMap from "@/leaflet/LiveAtlasLeafletMap";
|
||||
|
||||
/**
|
||||
* Leaflet map control providing a login/logout button which opens the login modal/logs out on click
|
||||
*/
|
||||
export class LoginControl extends Control {
|
||||
declare _map: LiveAtlasLeafletMap;
|
||||
declare options: ControlOptions;
|
||||
|
@ -25,6 +25,10 @@ export interface LogoControlOptions extends ControlOptions {
|
||||
text: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Leaflet map control which displays an arbitrary image or text with an optional link
|
||||
* Intended for use for dynmap logo components
|
||||
*/
|
||||
export class LogoControl extends Control {
|
||||
declare options: LogoControlOptions;
|
||||
|
||||
|
102
src/util.ts
102
src/util.ts
@ -22,7 +22,7 @@ import {
|
||||
LiveAtlasDimension,
|
||||
LiveAtlasGlobalMessageConfig,
|
||||
LiveAtlasLocation,
|
||||
LiveAtlasMessageConfig,
|
||||
LiveAtlasMessageConfig, LiveAtlasParsedUrl,
|
||||
} from "@/index";
|
||||
import {notify} from "@kyvg/vue3-notification";
|
||||
import {globalMessages, serverMessages} from "../messages";
|
||||
@ -34,6 +34,11 @@ export const titleColoursRegex = /§[0-9a-f]/ig;
|
||||
export const netherWorldNameRegex = /[_\s]?nether([\s_]|$)/i;
|
||||
export const endWorldNameRegex = /(^|[_\s])end([\s_]|$)/i;
|
||||
|
||||
/**
|
||||
* Calculates 24 hour time of day and the current day from the given server time
|
||||
* @param {number} serverTime Server time in ticks
|
||||
* @returns The equivalent 24 hour time, current day and whether it is currently day or night
|
||||
*/
|
||||
export const getMinecraftTime = (serverTime: number) => {
|
||||
const day = serverTime >= 0 && serverTime < 13700;
|
||||
|
||||
@ -51,14 +56,26 @@ export const getMinecraftTime = (serverTime: number) => {
|
||||
};
|
||||
}
|
||||
|
||||
export const parseUrl = (url: URL) => {
|
||||
/**
|
||||
* Parses the given {@link URL} into a {@link LiveAtlasParsedUrl}, if the URL matches any known URL formats
|
||||
* @param {URL} url The URL to parse
|
||||
* @returns {LiveAtlasParsedUrl | null} A LiveAtlasParsedUrl if the provided URL matched any known URL formats,
|
||||
* otherwise null
|
||||
*/
|
||||
export const parseUrl = (url: URL): LiveAtlasParsedUrl | null => {
|
||||
const query = new URLSearchParams(url.search),
|
||||
hash = url.hash.replace('#', '');
|
||||
|
||||
return hash ? parseMapHash(hash) : parseMapSearchParams(query);
|
||||
}
|
||||
|
||||
export const parseMapHash = (hash: string) => {
|
||||
/**
|
||||
* Parses the given hash into a {@link LiveAtlasParsedUrl}, if the hash matches the LiveAtlas URL hash format
|
||||
* @param {string} hash The hash to parse
|
||||
* @returns {LiveAtlasParsedUrl | null} A LiveAtlasParsedUrl if the provided hash matched the LiveAtlas URL
|
||||
* hash format, otherwise null
|
||||
*/
|
||||
export const parseMapHash = (hash: string): LiveAtlasParsedUrl | null => {
|
||||
const parts = hash.replace('#', '').split(';');
|
||||
|
||||
const world = parts[0] || undefined,
|
||||
@ -81,7 +98,13 @@ export const parseMapHash = (hash: string) => {
|
||||
});
|
||||
}
|
||||
|
||||
export const parseMapSearchParams = (query: URLSearchParams) => {
|
||||
/**
|
||||
* Parses the given {@link URLSearchParams} into a {@link LiveAtlasParsedUrl}, if it matches any known query string formats
|
||||
* @param {URLSearchParams} query The URLSearchParams to parse
|
||||
* @returns {LiveAtlasParsedUrl | null} A LiveAtlasParsedUrl if the provided hash matched the LiveAtlas URL
|
||||
* hash format, otherwise null
|
||||
*/
|
||||
export const parseMapSearchParams = (query: URLSearchParams): LiveAtlasParsedUrl | null => {
|
||||
const world = query.get('worldname') /* Dynmap */ || query.get('world') /* Pl3xmap */ || undefined,
|
||||
map = query.has('worldname') ? query.get('mapname') || undefined : undefined, //Dynmap only
|
||||
location = [
|
||||
@ -104,6 +127,15 @@ export const parseMapSearchParams = (query: URLSearchParams) => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the given {@link LiveAtlasParsedUrl} to ensure all required properties are present and have valid values
|
||||
* @param {LiveAtlasParsedUrl} parsed The parsed URL to validate
|
||||
* @return {LiveAtlasParsedUrl | null} The parsed URL, possibly modified to ensure validity, or null if it is invalid
|
||||
* and cannot be fixed
|
||||
* @see {@link parseMapSearchParams}
|
||||
* @see {@link parseMapHash}
|
||||
* @private
|
||||
*/
|
||||
const validateParsedUrl = (parsed: any) => {
|
||||
if(typeof parsed.zoom !== 'undefined' && (isNaN(parsed.zoom) || parsed.zoom < 0 || !isFinite(parsed.zoom))) {
|
||||
parsed.zoom = undefined;
|
||||
@ -116,6 +148,14 @@ const validateParsedUrl = (parsed: any) => {
|
||||
return parsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generates a LiveAtlas formatted URL hash representing the given {@link LiveAtlasMapDefinition}map, {@link Coordinate}
|
||||
* location and zoom level
|
||||
* @param {LiveAtlasMapDefinition} map The map
|
||||
* @param {Coordinate} location The location
|
||||
* @param {number} zoom The zoom level
|
||||
* @return {string} The URL hash (including the #), or an empty string if a valid hash cannot be constructed
|
||||
*/
|
||||
export const getUrlForLocation = (map: LiveAtlasMapDefinition, location: Coordinate, zoom: number): string => {
|
||||
const x = Math.round(location.x),
|
||||
y = Math.round(location.y),
|
||||
@ -129,6 +169,10 @@ export const getUrlForLocation = (map: LiveAtlasMapDefinition, location: Coordin
|
||||
return `#${map.world.name};${map.name};${locationString};${zoom}`;
|
||||
}
|
||||
|
||||
/**
|
||||
* Focuses the first html element which matches the given selector, if any
|
||||
* @param {string} selector The selector string
|
||||
*/
|
||||
export const focus = (selector: string) => {
|
||||
const element = document.querySelector(selector);
|
||||
|
||||
@ -139,31 +183,74 @@ export const focus = (selector: string) => {
|
||||
|
||||
const decodeTextarea = document.createElement('textarea');
|
||||
|
||||
/**
|
||||
* Decodes HTML entities in the given string using a <textarea>
|
||||
* @param {string} text The text to decode HTML entities in
|
||||
* @returns {string} The given text with any HTML entities decoded
|
||||
*/
|
||||
export const decodeHTMLEntities = (text: string) => {
|
||||
decodeTextarea.innerHTML = text;
|
||||
return decodeTextarea.textContent || '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Strips HTML from the given string using a contextual {@link DocumentFragment} and converts <br>s to spaces
|
||||
* @param {string} text The text to strip HTML from
|
||||
* @returns {string} The given text with HTML stripped
|
||||
*/
|
||||
export const stripHTML = (text: string) => {
|
||||
return documentRange.createContextualFragment(text.replace(brToSpaceRegex,' ')).textContent || '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Default success callback function for VueClipboard, will display a notification with the configured copy success
|
||||
* message
|
||||
*/
|
||||
export const clipboardSuccess = () => () => notify(useStore().state.messages.copyToClipboardSuccess);
|
||||
|
||||
/**
|
||||
* Default error callback function for VueClipboard, will display a notification with the configured copy error
|
||||
* message
|
||||
*/
|
||||
export const clipboardError = () => (e: Error) => {
|
||||
notify({ type: 'error', text: useStore().state.messages.copyToClipboardError });
|
||||
console.error('Error copying to clipboard', e);
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a {@link LiveAtlasMessageConfig} from the provided config object. The provided object will be checked for all
|
||||
* expected LiveAtlasMessageConfig messages, with fallback "Missing message" messages being used when a message is
|
||||
* missing from the provided object.
|
||||
* @param {Object} config Config object containing messages to include in the final LiveAtlasMessageConfig. Should
|
||||
* contain a complete or subset of keys from LiveAtlasMessageConfig, additional keys will be ignored.
|
||||
*/
|
||||
export const getMessages = (config: any = {}) => {
|
||||
return Object.assign(_getMessages(globalMessages, config),
|
||||
_getMessages(serverMessages, config)) as LiveAtlasMessageConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a {@link LiveAtlasGlobalMessageConfig} from the provided config object. The provided object will be checked
|
||||
* for all expected LiveAtlasGlobalMessageConfig messages, with fallback "Missing message" messages being used
|
||||
* when a message is missing from the provided object.
|
||||
* @param {Object} config Config object containing messages to include in the final LiveAtlasGlobalMessageConfig.
|
||||
* Should contain a complete or subset of keys from LiveAtlasGlobalMessageConfig, additional keys will be ignored.
|
||||
*/
|
||||
export const getGlobalMessages = (config: any = {}) => {
|
||||
return _getMessages(globalMessages, config) as LiveAtlasGlobalMessageConfig;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an object containing the keys present in the messageKeys object and the values present in the config object.
|
||||
*
|
||||
* For each key, the config object is checked for a corresponding value. A fallback "Missing message" value is used if
|
||||
* config object does not contain a value.
|
||||
* @param {Object} messageKeys The object to take the keys from
|
||||
* @param {Object} config The object to take the values from, if present
|
||||
* @see {@link getMessages}
|
||||
* @see {@link getGlobalMessages}
|
||||
* @private
|
||||
*/
|
||||
const _getMessages = (messageKeys: any, config: any = {}) => {
|
||||
const messages: any = {};
|
||||
|
||||
@ -190,7 +277,7 @@ export const getBounds = (x: number[], y: number[], z: number[]): LiveAtlasBound
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the bounds required to enclose the given array of {@see Coordinate}s
|
||||
* Determines the bounds required to enclose the given array of {@link Coordinate}s
|
||||
* Multiple dimension arrays are accepted and will be handled recursively
|
||||
* @param {Coordinate[]} points Points to determine the bounds for
|
||||
* @returns {LiveAtlasBounds} The calculated bounds
|
||||
@ -220,7 +307,7 @@ export const getBoundsFromPoints = (points: Coordinate[]): LiveAtlasBounds => {
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines the center point of the given {@see LiveAtlasBounds}
|
||||
* Determines the center point of the given {@link LiveAtlasBounds}
|
||||
* @param {LiveAtlasBounds} bounds The bounds to find the center point for
|
||||
* @return {LiveAtlasLocation} The center point
|
||||
*/
|
||||
@ -233,7 +320,8 @@ export const getMiddle = (bounds: LiveAtlasBounds): LiveAtlasLocation => {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an "allow-scripts" sandboxed <iframe> to be used by {@see runSandboxed}
|
||||
* Creates an "allow-scripts" sandboxed <iframe>
|
||||
* @see {@link runSandboxed}
|
||||
* @returns {Window} The iframe's contentWindow
|
||||
*/
|
||||
const createIframeSandbox = () => {
|
||||
|
@ -23,6 +23,12 @@ import LiveAtlasPolygon from "@/leaflet/vector/LiveAtlasPolygon";
|
||||
import {Coordinate, LiveAtlasAreaMarker} from "@/index";
|
||||
import {arePointsEqual, createPopup, isStyleEqual, tooltipOptions} from "@/util/paths";
|
||||
|
||||
/**
|
||||
* Creates a {@link LiveAtlasPolyline} or {@link LiveAtlasPolygon} with the given options
|
||||
* @param {LiveAtlasAreaMarker} options Marker options
|
||||
* @param {Function} converter Function for projecting the marker location onto the map
|
||||
* @return The created LiveAtlasPolyline or LiveAtlasPolygon
|
||||
*/
|
||||
export const createAreaLayer = (options: LiveAtlasAreaMarker, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => {
|
||||
const outline = !options.style.fillOpacity || (options.style.fillOpacity <= 0),
|
||||
points = options.points.map(projectPointsMapCallback, converter) as LatLngExpression[] | LatLngExpression[][],
|
||||
@ -39,6 +45,13 @@ export const createAreaLayer = (options: LiveAtlasAreaMarker, converter: Functio
|
||||
return area;
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates or creates a {@link LiveAtlasPolyline} or {@link LiveAtlasPolygon} with the given options
|
||||
* @param {LiveAtlasPolyline | LiveAtlasPolygon} area Optional existing LiveAtlasPolyline or LiveAtlasPolygon
|
||||
* @param {LiveAtlasAreaMarker} options Marker options
|
||||
* @param {Function} converter Function for projecting the marker location onto the map
|
||||
* @returns The created or updated LiveAtlasPolyline or LiveAtlasPolygon
|
||||
*/
|
||||
export const updateAreaLayer = (area: LiveAtlasPolyline | LiveAtlasPolygon | undefined, options: LiveAtlasAreaMarker, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => {
|
||||
if (!area) {
|
||||
return createAreaLayer(options, converter);
|
||||
@ -80,6 +93,14 @@ export const updateAreaLayer = (area: LiveAtlasPolyline | LiveAtlasPolygon | und
|
||||
return area;
|
||||
};
|
||||
|
||||
/**
|
||||
* Recursively applies the given function to the given array of {@link Coordinate}
|
||||
* @param point
|
||||
* @see {@link createAreaLayer}
|
||||
* @see {@link updateAreaLayer}
|
||||
* @returns Projected points as {@link LatLngExpression}
|
||||
* @private
|
||||
*/
|
||||
const projectPointsMapCallback = function(this: Function, point: Coordinate | Coordinate[] | Coordinate[][]): LatLngExpression | LatLngExpression[] {
|
||||
if(Array.isArray(point)) {
|
||||
return point.map(projectPointsMapCallback, this) as LatLngExpression[];
|
||||
@ -89,6 +110,14 @@ const projectPointsMapCallback = function(this: Function, point: Coordinate | Co
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates shape points for the given individual x y and z arrays
|
||||
* @param {number[]} x Array of x coordinates
|
||||
* @param {[number, number]} y Array of y coordinates
|
||||
* @param {number[]} z Array of z coordinates
|
||||
* @param outline Whether the resulting points will be used in a shape without a fill color
|
||||
* @returns Array of Coordinates
|
||||
*/
|
||||
export const getPoints = (x: number[], y: [number, number], z: number[], outline: boolean): Coordinate[] | Coordinate[][] => {
|
||||
if (x.length === 2) { /* Only 2 points */
|
||||
if (y[0] === y[1]) {
|
||||
@ -105,7 +134,16 @@ export const getPoints = (x: number[], y: [number, number], z: number[], outline
|
||||
}
|
||||
};
|
||||
|
||||
export const get3DBoxPoints = (x: number[], y: [number, number], z: number[]): Coordinate[][] => {
|
||||
/**
|
||||
* Calculates cuboid points for the given individual x y and z arrays
|
||||
* @param {number[]} x Array of x coordinates
|
||||
* @param {[number, number]} y Array of y coordinates
|
||||
* @param {number[]} z Array of z coordinates
|
||||
* @private
|
||||
* @see {@link getPoints}
|
||||
* @returns Array of Coordinates
|
||||
*/
|
||||
const get3DBoxPoints = (x: number[], y: [number, number], z: number[]): Coordinate[][] => {
|
||||
const maxX = x[0],
|
||||
minX = x[1],
|
||||
maxY = y[0],
|
||||
@ -148,7 +186,17 @@ export const get3DBoxPoints = (x: number[], y: [number, number], z: number[]): C
|
||||
];
|
||||
};
|
||||
|
||||
export const get2DBoxPoints = (x: number[], y: [number, number], z: number[], outline: boolean): Coordinate[] => {
|
||||
/**
|
||||
* Calculates rectangle points for the given individual x y and z arrays
|
||||
* @param {number[]} x Array of x coordinates
|
||||
* @param {[number, number]} y Array of y coordinates
|
||||
* @param {number[]} z Array of z coordinates
|
||||
* @param outline Whether the resulting points will be used in a shape without a fill color
|
||||
* @private
|
||||
* @see {@link getPoints}
|
||||
* @returns Array of Coordinates
|
||||
*/
|
||||
const get2DBoxPoints = (x: number[], y: [number, number], z: number[], outline: boolean): Coordinate[] => {
|
||||
const maxX = x[0],
|
||||
minX = x[1],
|
||||
minY = y[1],
|
||||
@ -173,7 +221,16 @@ export const get2DBoxPoints = (x: number[], y: [number, number], z: number[], ou
|
||||
}
|
||||
};
|
||||
|
||||
export const get3DShapePoints = (x: number[], y: [number, number], z: number[]): Coordinate[][] => {
|
||||
/**
|
||||
* Calculates non-cuobidal 3d shape points for the given individual x y and z arrays
|
||||
* @param {number[]} x Array of x coordinates
|
||||
* @param {[number, number]} y Array of y coordinates
|
||||
* @param {number[]} z Array of z coordinates
|
||||
* @private
|
||||
* @see {@link getPoints}
|
||||
* @returns Array of Coordinates
|
||||
*/
|
||||
const get3DShapePoints = (x: number[], y: [number, number], z: number[]): Coordinate[][] => {
|
||||
const toplist = [],
|
||||
botlist = [],
|
||||
polylist = [];
|
||||
@ -198,7 +255,17 @@ export const get3DShapePoints = (x: number[], y: [number, number], z: number[]):
|
||||
return polylist;
|
||||
};
|
||||
|
||||
export const get2DShapePoints = (x: number[], y: [number, number], z: number[], outline: boolean): Coordinate[] => {
|
||||
/**
|
||||
* Calculates non-quadrilateral 2d shape points for the given individual x y and z arrays
|
||||
* @param {number[]} x Array of x coordinates
|
||||
* @param {[number, number]} y Array of y coordinates
|
||||
* @param {number[]} z Array of z coordinates
|
||||
* @param outline Whether the resulting points will be used in a shape without a fill color
|
||||
* @private
|
||||
* @see {@link getPoints}
|
||||
* @returns Array of Coordinates
|
||||
*/
|
||||
const get2DShapePoints = (x: number[], y: [number, number], z: number[], outline: boolean): Coordinate[] => {
|
||||
const points = [];
|
||||
|
||||
for (let i = 0; i < x.length; i++) {
|
||||
|
@ -23,6 +23,12 @@ import LiveAtlasPolygon from "@/leaflet/vector/LiveAtlasPolygon";
|
||||
import {LiveAtlasCircleMarker} from "@/index";
|
||||
import {createPopup, tooltipOptions} from "@/util/paths";
|
||||
|
||||
/**
|
||||
* Creates a {@link LiveAtlasPolygon} with the given options
|
||||
* @param {LiveAtlasCircleMarker} options Marker options
|
||||
* @param {Function} converter Function for projecting the marker location onto the map
|
||||
* @return The created LiveAtlasPolygon
|
||||
*/
|
||||
export const createCircleLayer = (options: LiveAtlasCircleMarker, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => {
|
||||
const outline = !options.style.fillOpacity || (options.style.fillOpacity <= 0),
|
||||
points = getCirclePoints(options, converter, outline),
|
||||
@ -39,6 +45,13 @@ export const createCircleLayer = (options: LiveAtlasCircleMarker, converter: Fun
|
||||
return circle;
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates or creates a {@link LiveAtlasPolyline} with the given options
|
||||
* @param {?LiveAtlasPolyline | LiveAtlasPolygon | undefined} circle Optional existing LiveAtlasPolyline or LiveAtlasPolygons
|
||||
* @param {LiveAtlasCircleMarker} options Marker options
|
||||
* @param {Function} converter Function for projecting the marker location onto the map
|
||||
* @returns The created or updated LiveAtlasPolyline or LiveAtlasPolygon
|
||||
*/
|
||||
export const updateCircleLayer = (circle: LiveAtlasPolyline | LiveAtlasPolygon | undefined, options: LiveAtlasCircleMarker, converter: Function): LiveAtlasPolyline | LiveAtlasPolygon => {
|
||||
if (!circle) {
|
||||
return createCircleLayer(options, converter);
|
||||
@ -66,6 +79,13 @@ export const updateCircleLayer = (circle: LiveAtlasPolyline | LiveAtlasPolygon |
|
||||
return circle;
|
||||
}
|
||||
|
||||
/**
|
||||
* Calculates projected points for the given {@link LiveAtlasCircleMarker}
|
||||
* @param {LiveAtlasCircleMarker} options LiveAtlasCircleMarker to calculate points for
|
||||
* @param {Function} converter Function for projecting the points
|
||||
* @param outline Whether the resulting points will be used in a shape without a fill color
|
||||
* @returns Array of projected points
|
||||
*/
|
||||
export const getCirclePoints = (options: LiveAtlasCircleMarker, converter: Function, outline: boolean): LatLngExpression[] => {
|
||||
const points = [];
|
||||
|
||||
|
@ -21,11 +21,16 @@ import {useStore} from "@/store";
|
||||
import MapProvider from "@/providers/MapProvider";
|
||||
import DynmapMapProvider from "@/providers/DynmapMapProvider";
|
||||
|
||||
const expectedConfigVersion = 1;
|
||||
|
||||
const registeredProviders: Map<string, new (config: any) => MapProvider> = new Map();
|
||||
const serverProviders: Map<string, MapProvider> = new Map();
|
||||
const expectedConfigVersion = 1,
|
||||
registeredProviders: Map<string, new (config: any) => MapProvider> = new Map(),
|
||||
serverProviders: Map<string, MapProvider> = new Map();
|
||||
|
||||
/**
|
||||
* Registers the given {@link MapProvider} with the given id
|
||||
* Server entries in {@link LiveAtlasGlobalConfig} with the given id will use the given MapProvider
|
||||
* @param {string} id The id
|
||||
* @param {new (config: any) => MapProvider} provider The MapProvider
|
||||
*/
|
||||
export const registerMapProvider = (id: string, provider: new (config: any) => MapProvider) => {
|
||||
if(registeredProviders.has(id)) {
|
||||
throw new TypeError(`${id} is already registered`);
|
||||
@ -34,10 +39,22 @@ export const registerMapProvider = (id: string, provider: new (config: any) => M
|
||||
registeredProviders.set(id, provider);
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the MapProvider for the given server
|
||||
* @param {string} server Name of the server
|
||||
* @returns The MapProvider, if one exists
|
||||
*/
|
||||
export const getServerMapProvider = (server: string): MapProvider | undefined => {
|
||||
return serverProviders.get(server);
|
||||
}
|
||||
|
||||
/**
|
||||
* Attempts to load server definitions from the provided config object
|
||||
* @param {Object} config Config object to load server definitions from
|
||||
* @returns Map of loaded servers
|
||||
* @see {@link loadConfig}
|
||||
* @private
|
||||
*/
|
||||
const loadLiveAtlasConfig = (config: any): Map<string, LiveAtlasServerDefinition> => {
|
||||
const check = '\nCheck your server configuration in index.html is correct.',
|
||||
result = new Map<string, LiveAtlasServerDefinition>();
|
||||
@ -78,6 +95,12 @@ const loadLiveAtlasConfig = (config: any): Map<string, LiveAtlasServerDefinition
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Attempts to load a Dynmap server definition from the given object
|
||||
* @param {Object} config Config object to load from
|
||||
* @see {@link loadConfig}
|
||||
* @private
|
||||
*/
|
||||
const loadDefaultConfig = (config: DynmapUrlConfig): Map<string, LiveAtlasServerDefinition> => {
|
||||
const check = '\nCheck your standalone/config.js file exists and is being loaded correctly.';
|
||||
const result = new Map<string, LiveAtlasServerDefinition>();
|
||||
@ -97,6 +120,14 @@ const loadDefaultConfig = (config: DynmapUrlConfig): Map<string, LiveAtlasServer
|
||||
return result;
|
||||
};
|
||||
|
||||
/**
|
||||
* Attempts to load server definitions from the provided config object
|
||||
* If no servers definitions are present in the object, an attempt will be made to load a Dynmap server definition from
|
||||
* a global dynmap config object defined by standalone/config.js
|
||||
* @param {Object} config Config object to load server definitions from
|
||||
* @returns Map of loaded servers
|
||||
* @private
|
||||
*/
|
||||
export const loadConfig = (config: LiveAtlasGlobalConfig): Map<string, LiveAtlasServerDefinition> => {
|
||||
if (!config) {
|
||||
throw new ConfigurationError(`No configuration found.\nCheck for any syntax errors in your configuration in index.html. Your browser console may contain additional information.`);
|
||||
|
@ -23,6 +23,19 @@ const navigationKeys = new Set<string>([
|
||||
'End'
|
||||
]);
|
||||
|
||||
/**
|
||||
* Helper method for handling keyboard based selection, along with focus navigation within a set of HTML elements.
|
||||
*
|
||||
* The given {@link KeyboardEvent} will be checked for common navigation keys (currently arrow keys + home/end)
|
||||
* and the appropriate {@link HTMLElement} in the provided array of elements will be focused. No focus changes will occur
|
||||
* if none of the provided elements are currently focused
|
||||
*
|
||||
* The event will also be checked for an enter key press, and a click event will be simulated on the target element. The
|
||||
* element does not need to be in the provided element array for this to occur
|
||||
*
|
||||
* @param {KeyboardEvent} e The event to handle
|
||||
* @param {HTMLElement[]} elements The elements to consider for focusing
|
||||
*/
|
||||
export const handleKeyboardEvent = (e: KeyboardEvent, elements: HTMLElement[]) => {
|
||||
if(!e.target) {
|
||||
return;
|
||||
|
@ -25,7 +25,7 @@ const playerImageCache = new Map<string, HTMLImageElement>(),
|
||||
playerImageQueue: PlayerImageQueueEntry[] = [];
|
||||
|
||||
/**
|
||||
* Returns the corresponding pixel size for the given {@see LiveAtlasPlayerImageSize}
|
||||
* Returns the corresponding pixel size for the given {@link LiveAtlasPlayerImageSize}
|
||||
* @param {LiveAtlasPlayerImageSize} imageSize The image size to get the pixel size for
|
||||
* @returns The pixel size
|
||||
*/
|
||||
@ -42,12 +42,12 @@ export const getImagePixelSize = (imageSize: LiveAtlasPlayerImageSize) => {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates an {@see HTMLImageElement} containing an image representing the given {@see LiveAtlasPlayer}
|
||||
* at the given {@see LiveAtlasPlayerImageSize} and ensures it has loaded successfully
|
||||
* Creates an {@link HTMLImageElement} containing an image representing the given {@link LiveAtlasPlayer}
|
||||
* at the given {@link LiveAtlasPlayerImageSize} and ensures it has loaded successfully
|
||||
*
|
||||
* If an image has previously been loaded for the same player and image size, a cached copy of the image element
|
||||
* will be returned; Otherwise an attempt will be made to load the player image from the URL specified by the current
|
||||
* {@see LiveAtlasMapProvider}
|
||||
* {@link LiveAtlasMapProvider}
|
||||
*
|
||||
* The number of concurrent image loads is limited and additional loads will be queued. If this method is called
|
||||
* with the same player and image size multiple times, the load will only be queued once and the same element will be
|
||||
@ -55,7 +55,8 @@ export const getImagePixelSize = (imageSize: LiveAtlasPlayerImageSize) => {
|
||||
*
|
||||
* @param {LiveAtlasPlayer} player The player to retrieve the image for
|
||||
* @param {LiveAtlasPlayerImageSize} size The image size to retrieve
|
||||
* @returns {Promise<HTMLImageElement>} A promise which will resolve to a {@see HTMLImageElement} with the loaded player
|
||||
* @see {@link getDefaultPlayerImage}
|
||||
* @returns {Promise<HTMLImageElement>} A promise which will resolve to a HTMLImageElement with the loaded player
|
||||
* image as the src. The promise will reject if the image fails to load
|
||||
*/
|
||||
export const getPlayerImage = (player: LiveAtlasPlayer | string, size: LiveAtlasPlayerImageSize): Promise<HTMLImageElement> => {
|
||||
@ -105,7 +106,8 @@ export const getPlayerImage = (player: LiveAtlasPlayer | string, size: LiveAtlas
|
||||
|
||||
/**
|
||||
* Returns the default "Steve" player image. This image can be used as a placeholder whilst waiting for
|
||||
* {@see getPlayerImage} to complete
|
||||
* {@link getPlayerImage} to complete
|
||||
* @see {@link getPlayerImage}
|
||||
* @returns The default player image
|
||||
*/
|
||||
export const getDefaultPlayerImage = () => {
|
||||
@ -131,7 +133,7 @@ const tickPlayerImageQueue = () => {
|
||||
|
||||
/**
|
||||
* Clears the player image cache
|
||||
* Future calls to {@see getPlayerImage} will result in fresh image loads
|
||||
* Future calls to {@link getPlayerImage} will result in fresh image loads
|
||||
*/
|
||||
export const clearPlayerImageCache = () => {
|
||||
playerImageCache.clear();
|
||||
|
@ -22,6 +22,12 @@ import {Coordinate, LiveAtlasLineMarker} from "@/index";
|
||||
import {LatLngExpression} from "leaflet";
|
||||
import {createPopup, tooltipOptions} from "@/util/paths";
|
||||
|
||||
/**
|
||||
* Creates a {@link LiveAtlasPolyline} with the given options
|
||||
* @param {LiveAtlasLineMarker} options Marker options
|
||||
* @param {Function} converter Function for projecting the marker location onto the map
|
||||
* @return The created LiveAtlasPolyline
|
||||
*/
|
||||
export const createLineLayer = (options: LiveAtlasLineMarker, converter: Function): LiveAtlasPolyline => {
|
||||
const points = options.points.map(projectPointsMapCallback, converter),
|
||||
line = new LiveAtlasPolyline(points, options);
|
||||
@ -37,6 +43,13 @@ export const createLineLayer = (options: LiveAtlasLineMarker, converter: Functio
|
||||
return line;
|
||||
};
|
||||
|
||||
/**
|
||||
* Updates or creates a {@link LiveAtlasPolyline} with the given options
|
||||
* @param {?LiveAtlasPolyline} line Optional existing LiveAtlasPolyline
|
||||
* @param {LiveAtlasLineMarker} options Marker options
|
||||
* @param {Function} converter Function for projecting the marker location onto the map
|
||||
* @returns The created or updated LiveAtlasPolyline
|
||||
*/
|
||||
export const updateLineLayer = (line: LiveAtlasPolyline | undefined, options: LiveAtlasLineMarker, converter: Function): LiveAtlasPolyline => {
|
||||
if (!line) {
|
||||
return createLineLayer(options, converter);
|
||||
@ -62,6 +75,13 @@ export const updateLineLayer = (line: LiveAtlasPolyline | undefined, options: Li
|
||||
return line;
|
||||
}
|
||||
|
||||
/**
|
||||
* Recursively applies the given function to the given array of {@link Coordinate}
|
||||
* @param point
|
||||
* @see {@link createAreaLayer}
|
||||
* @see {@link updateAreaLayer}
|
||||
* @private
|
||||
*/
|
||||
const projectPointsMapCallback = function(point: Coordinate): LatLngExpression {
|
||||
if(Array.isArray(point)) {
|
||||
return projectPointsMapCallback(point);
|
||||
@ -71,6 +91,13 @@ const projectPointsMapCallback = function(point: Coordinate): LatLngExpression {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Calculates line points for the given individual x y and z arrays
|
||||
* @param {number[]} x Array of x coordinates
|
||||
* @param {[number, number]} y Array of y coordinates
|
||||
* @param {number[]} z Array of z coordinates
|
||||
* @returns Array of Coordinates
|
||||
*/
|
||||
export const getLinePoints = (x: number[], y: number[], z: number[]): Coordinate[] => {
|
||||
const points = [];
|
||||
|
||||
|
@ -53,6 +53,9 @@ let pendingUpdates: ComputedRef;
|
||||
const updateHandlers: Set<LiveAtlasMarkerUpdateCallback> = new Set();
|
||||
const setUpdateHandlers: { [key:string]: Set<LiveAtlasMarkerUpdateCallback>} = {};
|
||||
|
||||
/**
|
||||
* Starts handling of pending marker updates
|
||||
*/
|
||||
export const startUpdateHandling = () => {
|
||||
const store = useStore();
|
||||
|
||||
@ -65,6 +68,9 @@ export const startUpdateHandling = () => {
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Stops handling of pending marker updates
|
||||
*/
|
||||
export const stopUpdateHandling = () => {
|
||||
if(updateFrame) {
|
||||
cancelAnimationFrame(updateFrame);
|
||||
@ -72,14 +78,27 @@ export const stopUpdateHandling = () => {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the given callback as a global handler for marker updates
|
||||
* @param {LiveAtlasMarkerUpdateCallback} callback The callback
|
||||
*/
|
||||
export const registerUpdateHandler = (callback: LiveAtlasMarkerUpdateCallback) => {
|
||||
updateHandlers.add(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the given callback as a global handler for marker updates
|
||||
* @param {LiveAtlasMarkerUpdateCallback} callback The callback
|
||||
*/
|
||||
export const unregisterUpdateHandler = (callback: LiveAtlasMarkerUpdateCallback) => {
|
||||
updateHandlers.delete(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the given callback as a handler for marker updates in the given marker set
|
||||
* @param {LiveAtlasMarkerUpdateCallback} callback The callback
|
||||
* @param {string} set: The marker set id
|
||||
*/
|
||||
export const registerSetUpdateHandler = (callback: LiveAtlasMarkerUpdateCallback, set: string) => {
|
||||
if(!setUpdateHandlers[set]) {
|
||||
setUpdateHandlers[set] = new Set();
|
||||
@ -88,6 +107,11 @@ export const registerSetUpdateHandler = (callback: LiveAtlasMarkerUpdateCallback
|
||||
setUpdateHandlers[set].add(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters the given callback as a handler for marker updates in the given marker set
|
||||
* @param {LiveAtlasMarkerUpdateCallback} callback The callback
|
||||
* @param {string} set: The marker set id
|
||||
*/
|
||||
export const unregisterSetUpdateHandler = (callback: LiveAtlasMarkerUpdateCallback, set: string) => {
|
||||
if(!setUpdateHandlers[set]) {
|
||||
return;
|
||||
@ -96,6 +120,12 @@ export const unregisterSetUpdateHandler = (callback: LiveAtlasMarkerUpdateCallba
|
||||
setUpdateHandlers[set].delete(callback);
|
||||
}
|
||||
|
||||
/**
|
||||
* Handles pending marker updates, if any exist
|
||||
* Up to 10 updates will be taken from the list and the appropriate registered update handlers will be called
|
||||
* If further updates remain, an animation frame will be scheduled for further calls
|
||||
* @private
|
||||
*/
|
||||
const handlePendingUpdates = async () => {
|
||||
const store = useStore(),
|
||||
updates = await store.dispatch(ActionTypes.POP_MARKER_UPDATES, 10);
|
||||
@ -116,6 +146,16 @@ const handlePendingUpdates = async () => {
|
||||
}
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates the appropriate type of marker layer for the given {@link LiveAtlasMarker}
|
||||
* @param {LiveAtlasMarker} options Marker options
|
||||
* @param {Function} converter Function for projecting the marker location onto the map
|
||||
* @returns The created layer
|
||||
* @see createPointLayer
|
||||
* @see createAreaLayer
|
||||
* @see createCircleLayer
|
||||
* @see createLineLayer
|
||||
*/
|
||||
export const createMarkerLayer = (options: LiveAtlasMarker, converter: Function): Layer => {
|
||||
switch(options.type) {
|
||||
case LiveAtlasMarkerType.POINT:
|
||||
@ -129,6 +169,17 @@ export const createMarkerLayer = (options: LiveAtlasMarker, converter: Function)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Updates or creates an appropriate type of marker layer with the given options
|
||||
* @param {?Layer} marker Optional existing marker layer to update
|
||||
* @param {?LiveAtlasMarker} options Marker options
|
||||
* @param {Function} converter Function for projecting the marker location onto the map
|
||||
* @returns The created layer
|
||||
* @see updatePointLayer
|
||||
* @see updateAreaLayer
|
||||
* @see updateCircleLayer
|
||||
* @see updateLineLayer
|
||||
*/
|
||||
export const updateMarkerLayer = (marker: Layer | undefined, options: LiveAtlasMarker, converter: Function): Layer => {
|
||||
switch(options.type) {
|
||||
case LiveAtlasMarkerType.POINT:
|
||||
|
@ -24,11 +24,23 @@ export const tooltipOptions = {
|
||||
interactive: false,
|
||||
};
|
||||
|
||||
/**
|
||||
* Determines if the 2 given arrays of {@link LatLngExpression} are equal by comparing the JSON serialised representations
|
||||
* @param {LatLngExpression | LatLngExpression[] | LatLngExpression[][] | LatLngExpression[][][]} oldPoints Points to compare
|
||||
* @param {LatLngExpression | LatLngExpression[] | LatLngExpression[][] | LatLngExpression[][][]} newPoints Other points to compare
|
||||
* @return Whether both arrays of points are considered equal
|
||||
*/
|
||||
export const arePointsEqual = (oldPoints: LatLngExpression | LatLngExpression[] | LatLngExpression[][] | LatLngExpression[][][],
|
||||
newPoints: LatLngExpression | LatLngExpression[] | LatLngExpression[][] | LatLngExpression[][][]) => {
|
||||
return JSON.stringify(oldPoints) === JSON.stringify(newPoints);
|
||||
}
|
||||
|
||||
/**
|
||||
* Determines if the 2 given {@link PathOptions} are equal by comapring their properties
|
||||
* @param {PathOptions} oldStyle PathOptions to compare
|
||||
* @param {PathOptions} newStyle Other PathOptions to compare
|
||||
* @return Whether both PathOptions are considered equal
|
||||
*/
|
||||
export const isStyleEqual = (oldStyle: PathOptions, newStyle: PathOptions) => {
|
||||
return oldStyle && newStyle
|
||||
&& (oldStyle.color === newStyle.color)
|
||||
@ -38,6 +50,12 @@ export const isStyleEqual = (oldStyle: PathOptions, newStyle: PathOptions) => {
|
||||
&& (oldStyle.fillOpacity === newStyle.fillOpacity)
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a popup element for the given marker
|
||||
* @param {LiveAtlasPointMarker} options Marker options
|
||||
* @param {string} className Classname to add to the popup element
|
||||
* @returns {HTMLSpanElement} The marker element
|
||||
*/
|
||||
export const createPopup = (options: LiveAtlasPathMarker, className: string): HTMLElement => {
|
||||
const popup = document.createElement('span');
|
||||
|
||||
|
@ -14,12 +14,18 @@
|
||||
* limitations under the License.
|
||||
*/
|
||||
|
||||
import {LeafletMouseEvent, Marker} from "leaflet";
|
||||
import {LeafletMouseEvent} from "leaflet";
|
||||
import {GenericIcon} from "@/leaflet/icon/GenericIcon";
|
||||
import {GenericMarker} from "@/leaflet/marker/GenericMarker";
|
||||
import {LiveAtlasPointMarker} from "@/index";
|
||||
|
||||
export const createPointLayer = (options: LiveAtlasPointMarker, converter: Function): Marker => {
|
||||
/**
|
||||
* Creates a {@link GenericMarker} with the given options
|
||||
* @param {LiveAtlasPointMarker} options Marker options
|
||||
* @param {Function} converter Function for projecting the marker location onto the map
|
||||
* @return The created GenericMarker
|
||||
*/
|
||||
export const createPointLayer = (options: LiveAtlasPointMarker, converter: Function): GenericMarker => {
|
||||
const marker = new GenericMarker(converter(options.location), options);
|
||||
|
||||
marker.on('click', (e: LeafletMouseEvent) => {
|
||||
@ -35,7 +41,14 @@ export const createPointLayer = (options: LiveAtlasPointMarker, converter: Funct
|
||||
return marker;
|
||||
};
|
||||
|
||||
export const updatePointLayer = (marker: Marker | undefined, options: LiveAtlasPointMarker, converter: Function): Marker => {
|
||||
/**
|
||||
* Updates or creates a {@link GenericMarker} with the given options
|
||||
* @param {?GenericMarker} marker Optional existing GenericMarker to update
|
||||
* @param {LiveAtlasPointMarker} options Marker options
|
||||
* @param {Function} converter Function for projecting the marker location onto the map
|
||||
* @returns The created or updated GenericMarker
|
||||
*/
|
||||
export const updatePointLayer = (marker: GenericMarker | undefined, options: LiveAtlasPointMarker, converter: Function): GenericMarker => {
|
||||
if (!marker) {
|
||||
return createPointLayer(options, converter);
|
||||
}
|
||||
@ -71,6 +84,12 @@ export const updatePointLayer = (marker: Marker | undefined, options: LiveAtlasP
|
||||
return marker;
|
||||
};
|
||||
|
||||
/**
|
||||
* Creates a popup element for the given marker
|
||||
* @param {LiveAtlasPointMarker} options Marker options
|
||||
* @returns {HTMLSpanElement} The marker element
|
||||
* @private
|
||||
*/
|
||||
const createPopup = (options: LiveAtlasPointMarker) => {
|
||||
const popup = document.createElement('span');
|
||||
|
||||
|
@ -21,6 +21,10 @@ const app = document.getElementById('app'),
|
||||
splashErrorMessage = document.getElementById('splash__error-message'),
|
||||
splashRetry = document.getElementById('splash__error-retry');
|
||||
|
||||
/**
|
||||
* Shows the LiveAtlas splash screen, if it isn't already visible
|
||||
* @param reset If true, any existing errors or retry counts will be removed
|
||||
*/
|
||||
export const showSplash = function(reset: boolean) {
|
||||
if(!splash || !app) {
|
||||
return;
|
||||
@ -48,6 +52,10 @@ export const showSplash = function(reset: boolean) {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Hides the LiveAtlas splash screen, if it is visible
|
||||
* The splash screen is not fully hidden immediately, as it has a CSS defined fade out animation
|
||||
*/
|
||||
export const hideSplash = () => {
|
||||
if(!splash || !app) {
|
||||
return;
|
||||
@ -63,6 +71,16 @@ export const hideSplash = () => {
|
||||
});
|
||||
};
|
||||
|
||||
/**
|
||||
* Displays the given error message on the splash screen
|
||||
* If the splash screen is not currently visible {@link showSplash} should also be called
|
||||
* @see {@link showSplash}
|
||||
* @param {string} message The error message to display
|
||||
* @param {boolean} fatal If true the loading spinner will be hidden to indicate a fatal error. This does not stop any
|
||||
* ongoing processes the loading indicator was indicating
|
||||
* @param {?number} attempts Optional number of previous retry attempts that occurred before the current error. If
|
||||
* provided this will be displayed after the error message
|
||||
*/
|
||||
export const showSplashError = (message: string, fatal: boolean, attempts?: number) => {
|
||||
if(splashError) {
|
||||
splashError.setAttribute('aria-hidden', 'false');
|
||||
|
Loading…
Reference in New Issue
Block a user