Add geolocation
This commit is contained in:
@@ -61,6 +61,7 @@ class Odidere {
|
||||
this.isResetPending = false;
|
||||
this.isScrollPending = false;
|
||||
this.isStopPending = false;
|
||||
this.locationData = null;
|
||||
this.mediaRecorder = null;
|
||||
this.wakeLock = null;
|
||||
this.pendingDeleteId = null;
|
||||
@@ -95,6 +96,7 @@ class Odidere {
|
||||
this.$chat = document.getElementById('chat');
|
||||
this.$chatLoading = document.getElementById('chat-loading');
|
||||
this.$fileInput = document.getElementById('file-input');
|
||||
this.$location = document.getElementById('location');
|
||||
this.$model = document.getElementById('model');
|
||||
this.$ptt = document.getElementById('ptt');
|
||||
this.$reset = document.getElementById('reset');
|
||||
@@ -170,6 +172,7 @@ class Odidere {
|
||||
el.remove();
|
||||
});
|
||||
this.#clearAttachments();
|
||||
this.#clearLocation();
|
||||
this.$textInput.value = '';
|
||||
this.$textInput.style.height = 'auto';
|
||||
this.totalTokens = 0;
|
||||
@@ -231,6 +234,11 @@ class Odidere {
|
||||
this.document.addEventListener('click', (e) => this.#handleScrollCancel(e));
|
||||
this.document.addEventListener('click', (e) => this.#handleDeleteCancel(e));
|
||||
|
||||
// Location toggle.
|
||||
this.$location.addEventListener('click', () =>
|
||||
this.#handleLocationToggle(),
|
||||
);
|
||||
|
||||
// File attachment.
|
||||
this.$attach.addEventListener('click', () => this.$fileInput.click());
|
||||
this.$fileInput.addEventListener('change', (e) =>
|
||||
@@ -656,6 +664,38 @@ class Odidere {
|
||||
this.#submitText();
|
||||
};
|
||||
|
||||
/**
|
||||
* #handleLocationToggle toggles GPS location inclusion.
|
||||
* When enabled, requests the user's current position via the Geolocation API.
|
||||
* If denied or unavailable, silently leaves the button off.
|
||||
*/
|
||||
#handleLocationToggle = () => {
|
||||
if (this.locationData) {
|
||||
// Turn off.
|
||||
this.locationData = null;
|
||||
this.$location.classList.remove(
|
||||
'compose__action-btn--location',
|
||||
'active',
|
||||
);
|
||||
this.#updateSendButtonState();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!navigator.geolocation) {
|
||||
return;
|
||||
}
|
||||
|
||||
navigator.geolocation.getCurrentPosition(
|
||||
(position) => {
|
||||
this.locationData = position;
|
||||
this.$location.classList.add('compose__action-btn--location', 'active');
|
||||
this.#updateSendButtonState();
|
||||
},
|
||||
// On error, leave the button off; user must retry manually.
|
||||
() => {},
|
||||
);
|
||||
};
|
||||
|
||||
/**
|
||||
* #handleTextareaInput adjusts textarea height to fit content.
|
||||
*/
|
||||
@@ -1469,7 +1509,8 @@ class Odidere {
|
||||
this.currentController = new AbortController();
|
||||
|
||||
try {
|
||||
const hasNewInput = text || this.attachments.length > 0;
|
||||
const hasNewInput =
|
||||
text || this.attachments.length > 0 || this.locationData;
|
||||
|
||||
// Build messages array from active path + current user message.
|
||||
const activePath = this.getActivePath();
|
||||
@@ -1500,8 +1541,9 @@ class Odidere {
|
||||
payload.system_message = systemMessage;
|
||||
}
|
||||
|
||||
// Clear attachments after building payload (before async operations).
|
||||
// Clear attachments and location after building payload (before async operations).
|
||||
this.#clearAttachments();
|
||||
this.#clearLocation();
|
||||
|
||||
// For text-only requests with new input, add to history and render
|
||||
// immediately. Skip when continuing conversation (no new user message).
|
||||
@@ -1789,6 +1831,12 @@ class Odidere {
|
||||
textParts.push(text);
|
||||
}
|
||||
|
||||
// Include GPS location if enabled (appended at end).
|
||||
if (this.locationData) {
|
||||
const locationText = JSON.stringify(this.locationData, null, 2);
|
||||
textParts.push(locationText);
|
||||
}
|
||||
|
||||
const combinedText = textParts.join('\n\n');
|
||||
|
||||
// If no images, return simple string content.
|
||||
@@ -1825,8 +1873,9 @@ class Odidere {
|
||||
#updateSendButtonState() {
|
||||
const hasText = this.$textInput.value.trim().length > 0;
|
||||
const hasAttachments = this.attachments.length > 0;
|
||||
const hasLocation = this.locationData !== null;
|
||||
const hasHistory = this.messagesMap.size > 0;
|
||||
const enabled = hasText || hasAttachments || hasHistory;
|
||||
const enabled = hasText || hasAttachments || hasLocation || hasHistory;
|
||||
this.$send.disabled = !enabled;
|
||||
this.$send.setAttribute(
|
||||
'aria-label',
|
||||
@@ -2705,6 +2754,14 @@ class Odidere {
|
||||
this.#updateSendButtonState();
|
||||
}
|
||||
|
||||
/**
|
||||
* #clearLocation clears location data and resets the button state.
|
||||
*/
|
||||
#clearLocation() {
|
||||
this.locationData = null;
|
||||
this.$location.classList.remove('compose__action-btn--location', 'active');
|
||||
}
|
||||
|
||||
/**
|
||||
* #clearAttachments removes all attachments.
|
||||
*/
|
||||
|
||||
Reference in New Issue
Block a user