From 153dbc0b0e6969fe1a1953959d5678ef90fbed8a Mon Sep 17 00:00:00 2001 From: ShivamChaudhary Date: Sat, 21 Feb 2026 01:49:52 +0530 Subject: [PATCH] fix: respect geo-location settings when creating notes from templates --- src/actions.ts | 12 +++++++- src/utils/geolocation.ts | 62 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 73 insertions(+), 1 deletion(-) create mode 100644 src/utils/geolocation.ts diff --git a/src/actions.ts b/src/actions.ts index 975619d..32ce933 100644 --- a/src/actions.ts +++ b/src/actions.ts @@ -3,6 +3,7 @@ import { NewNote } from "./parser"; import { getSelectedFolder } from "./utils/folders"; import { applyTagToNote, getAnyTagWithTitle } from "./utils/tags"; import { ApplyTagsWhileInsertingSetting } from "./settings"; +import { getGeoLocationForNote } from "./utils/geolocation"; export enum TemplateAction { NewNote = "newNote", @@ -25,12 +26,21 @@ const performInsertTextAction = async (template: NewNote) => { const performNewNoteAction = async (template: NewNote, isTodo: 0 | 1) => { const folderId = template.folder ? template.folder : await getSelectedFolder(); - const notePayload = { body: template.body, parent_id: folderId, title: template.title, is_todo: isTodo }; + const notePayload: Record = { body: template.body, parent_id: folderId, title: template.title, is_todo: isTodo }; if (isTodo && template.todo_due) { notePayload["todo_due"] = template.todo_due; } + const geoLocation = await getGeoLocationForNote(); + if (geoLocation) { + notePayload["latitude"] = geoLocation.latitude; + notePayload["longitude"] = geoLocation.longitude; + if (geoLocation.altitude !== undefined) { + notePayload["altitude"] = geoLocation.altitude; + } + } + const note = await joplin.data.post(["notes"], null, notePayload); await joplin.commands.execute("openNote", note.id); for (const tag of template.tags) { diff --git a/src/utils/geolocation.ts b/src/utils/geolocation.ts new file mode 100644 index 0000000..ac8d0f5 --- /dev/null +++ b/src/utils/geolocation.ts @@ -0,0 +1,62 @@ +import joplin from "api"; + +export interface GeoLocation { + latitude: number; + longitude: number; + altitude?: number; +} + +/** + * Checks whether the user has enabled "Save geo-location with notes" in Joplin settings. + */ +export const isGeoLocationEnabled = async (): Promise => { + try { + const value = await joplin.settings.globalValue("note.saveGeolocation"); + return value === true; + } catch { + // If the setting key is unavailable, default to false + return false; + } +}; + +/** + * Gets the current GPS coordinates using the browser's geolocation API. + * Joplin runs on Electron, so navigator.geolocation is available. + * Returns null if geolocation is unavailable or the user denies permission. + */ +export const getCurrentLocation = (): Promise => { + return new Promise((resolve) => { + if (typeof navigator === "undefined" || !navigator.geolocation) { + resolve(null); + return; + } + + navigator.geolocation.getCurrentPosition( + (position) => { + resolve({ + latitude: position.coords.latitude, + longitude: position.coords.longitude, + altitude: position.coords.altitude ?? undefined, + }); + }, + () => { + // User denied or error — resolve with null gracefully + resolve(null); + }, + { + timeout: 5000, + maximumAge: 60000, + } + ); + }); +}; + +/** + * Returns geo-location data to attach to a note, respecting the Joplin setting. + * Returns null if the setting is disabled or location cannot be determined. + */ +export const getGeoLocationForNote = async (): Promise => { + const enabled = await isGeoLocationEnabled(); + if (!enabled) return null; + return await getCurrentLocation(); +};