import Constants from "../Models/Constants" import { SpecialVisualizationState } from "../UI/SpecialVisualization" export interface MaprouletteTask { name: string description: string instruction: string } export const maprouletteStatus = [ "Open", "Fixed", "False_positive", "Skipped", "Deleted", "Already fixed", "Too_Hard", "Disabled", ] as const export type MaprouletteStatus = (typeof maprouletteStatus)[number] export default class Maproulette { public static readonly defaultEndpoint = "https://maproulette.org/api/v2" public static readonly STATUS_OPEN = 0 public static readonly STATUS_FIXED = 1 public static readonly STATUS_FALSE_POSITIVE = 2 public static readonly STATUS_SKIPPED = 3 public static readonly STATUS_DELETED = 4 public static readonly STATUS_ALREADY_FIXED = 5 public static readonly STATUS_TOO_HARD = 6 public static readonly STATUS_DISABLED = 9 public static singleton = new Maproulette() /* * The API endpoint to use */ endpoint: string /** * The API key to use for all requests */ private readonly apiKey: string /** * Creates a new Maproulette instance * @param endpoint The API endpoint to use */ constructor(endpoint?: string) { this.endpoint = endpoint ?? Maproulette.defaultEndpoint if (!this.endpoint) { throw "MapRoulette endpoint is undefined. Make sure that `Maproulette.defaultEndpoint` is defined on top of the class" } this.apiKey = Constants.MaprouletteApiKey } /** * Converts a status text into the corresponding number * * Maproulette.codeToIndex("Created") // => 0 * Maproulette.codeToIndex("qdsf") // => undefined * */ public static codeToIndex(code: string): number | undefined { if (code === "Created") { return Maproulette.STATUS_OPEN } const i = maprouletteStatus.indexOf(code) if (i < 0) { return undefined } return i } /** * Close a task; might throw an error * * Also see:https://maproulette.org/docs/swagger-ui/index.html?url=/assets/swagger.json&docExpansion=none#/Task/setTaskStatus * @param taskId The task to close * @param status A number indicating the status. Use MapRoulette.STATUS_* * @param options Additional settings to pass. Refer to the API-docs for more information */ async closeTask( taskId: number, status = Maproulette.STATUS_FIXED, state: SpecialVisualizationState, options?: { comment?: string tags?: string requestReview?: boolean completionResponses?: Record } ): Promise { console.log("Maproulette: setting", `${this.endpoint}/task/${taskId}/${status}`, options) options ??= {} const userdetails = state.osmConnection.userDetails.data options.tags = `MapComplete MapComplete:${state.theme.id}; userid: ${userdetails?.uid}; username: ${userdetails?.name}` const response = await fetch(`${this.endpoint}/task/${taskId}/${status}`, { method: "PUT", headers: { "Content-Type": "application/json", apiKey: this.apiKey, }, body: JSON.stringify(options), }) if (response.status !== 204) { console.log(`Failed to close task: ${response.status}`) throw `Failed to close task: ${response.status}` } } }