From 04aef362e24fd4a50f8c5673f2b24658381d9395 Mon Sep 17 00:00:00 2001 From: Debanjum Singh Solanky Date: Mon, 30 Sep 2024 03:15:50 -0700 Subject: [PATCH] Default to using system clock to infer user timezone on js clients Using system clock to infer user timezone on clients makes Khoj more robust to provide location aware responses. Previously only ip based location was used to infer timezone via API. This didn't provide any decent fallback when calls to ipapi failed or Khoj was being run in offline mode --- src/interface/desktop/chat.html | 2 +- src/interface/desktop/shortcut.html | 2 +- src/interface/obsidian/src/chat_view.ts | 22 ++++++++++------------ src/interface/web/app/automations/page.tsx | 6 ++++-- src/interface/web/app/chat/page.tsx | 4 +++- src/interface/web/app/common/utils.ts | 16 +++++----------- src/interface/web/app/share/chat/page.tsx | 4 +++- 7 files changed, 27 insertions(+), 29 deletions(-) diff --git a/src/interface/desktop/chat.html b/src/interface/desktop/chat.html index cd47dae5..a6ae9a15 100644 --- a/src/interface/desktop/chat.html +++ b/src/interface/desktop/chat.html @@ -61,7 +61,7 @@ let city = null; let countryName = null; let countryCode = null; - let timezone = null; + let timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; let chatMessageState = { newResponseTextEl: null, newResponseEl: null, diff --git a/src/interface/desktop/shortcut.html b/src/interface/desktop/shortcut.html index 4b07b8ea..9c760019 100644 --- a/src/interface/desktop/shortcut.html +++ b/src/interface/desktop/shortcut.html @@ -312,7 +312,7 @@ let city = null; let countryName = null; let countryCode = null; - let timezone = null; + let timezone = Intl.DateTimeFormat().resolvedOptions().timeZone; fetch("https://ipapi.co/json") .then(response => response.json()) diff --git a/src/interface/obsidian/src/chat_view.ts b/src/interface/obsidian/src/chat_view.ts index f27098ca..ed23bff0 100644 --- a/src/interface/obsidian/src/chat_view.ts +++ b/src/interface/obsidian/src/chat_view.ts @@ -33,10 +33,10 @@ interface ChatMessageState { } interface Location { - region: string; - city: string; - countryName: string; - countryCode: string; + region?: string; + city?: string; + countryName?: string; + countryCode?: string; timezone: string; } @@ -44,7 +44,7 @@ export class KhojChatView extends KhojPaneView { result: string; setting: KhojSetting; waitingForLocation: boolean; - location: Location; + location: Location = { timezone: Intl.DateTimeFormat().resolvedOptions().timeZone }; keyPressTimeout: NodeJS.Timeout | null = null; userMessages: string[] = []; // Store user sent messages for input history cycling currentMessageIndex: number = -1; // Track current message index in userMessages array @@ -1058,13 +1058,11 @@ export class KhojChatView extends KhojPaneView { n: this.setting.resultsCount, stream: true, ...(!!conversationId && { conversation_id: conversationId }), - ...(!!this.location && { - city: this.location.city, - region: this.location.region, - country: this.location.countryName, - country_code: this.location.countryCode, - timezone: this.location.timezone, - }), + ...(!!this.location && this.location.city && { city: this.location.city }), + ...(!!this.location && this.location.region && { region: this.location.region }), + ...(!!this.location && this.location.countryName && { country: this.location.countryName }), + ...(!!this.location && this.location.countryCode && { country_code: this.location.countryCode }), + ...(!!this.location && this.location.timezone && { timezone: this.location.timezone }), }; let newResponseEl = this.createKhojResponseDiv(); diff --git a/src/interface/web/app/automations/page.tsx b/src/interface/web/app/automations/page.tsx index 06a828d8..f2d06c23 100644 --- a/src/interface/web/app/automations/page.tsx +++ b/src/interface/web/app/automations/page.tsx @@ -518,12 +518,14 @@ function EditCard(props: EditCardProps) { updateQueryUrl += `&subject=${encodeURIComponent(values.subject)}`; } updateQueryUrl += `&crontime=${encodeURIComponent(cronFrequency)}`; - if (props.locationData) { + if (props.locationData && props.locationData.city) updateQueryUrl += `&city=${encodeURIComponent(props.locationData.city)}`; + if (props.locationData && props.locationData.region) updateQueryUrl += `®ion=${encodeURIComponent(props.locationData.region)}`; + if (props.locationData && props.locationData.country) updateQueryUrl += `&country=${encodeURIComponent(props.locationData.country)}`; + if (props.locationData && props.locationData.timezone) updateQueryUrl += `&timezone=${encodeURIComponent(props.locationData.timezone)}`; - } let method = props.createNew ? "POST" : "PUT"; diff --git a/src/interface/web/app/chat/page.tsx b/src/interface/web/app/chat/page.tsx index 37a894e9..7d87fd81 100644 --- a/src/interface/web/app/chat/page.tsx +++ b/src/interface/web/app/chat/page.tsx @@ -136,7 +136,9 @@ export default function Chat() { const [uploadedFiles, setUploadedFiles] = useState([]); const [image64, setImage64] = useState(""); - const locationData = useIPLocationData(); + const locationData = useIPLocationData() || { + timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, + }; const authenticatedData = useAuthenticatedData(); const isMobileWidth = useIsMobileWidth(); diff --git a/src/interface/web/app/common/utils.ts b/src/interface/web/app/common/utils.ts index b5dbfec8..1e7337b8 100644 --- a/src/interface/web/app/common/utils.ts +++ b/src/interface/web/app/common/utils.ts @@ -2,14 +2,10 @@ import { useEffect, useState } from "react"; import useSWR from "swr"; export interface LocationData { - ip: string; - city: string; - region: string; - country: string; - countryCode: string; - postal: string; - latitude: number; - longitude: number; + city?: string; + region?: string; + country?: string; + countryCode?: string; timezone: string; } @@ -51,9 +47,7 @@ export function useIPLocationData() { { revalidateOnFocus: false }, ); - if (locationDataError) return null; - if (!locationData) return null; - + if (locationDataError || !locationData) return; return locationData; } diff --git a/src/interface/web/app/share/chat/page.tsx b/src/interface/web/app/share/chat/page.tsx index 116a7f7c..9bc5f12d 100644 --- a/src/interface/web/app/share/chat/page.tsx +++ b/src/interface/web/app/share/chat/page.tsx @@ -111,7 +111,9 @@ export default function SharedChat() { const [paramSlug, setParamSlug] = useState(undefined); const [image64, setImage64] = useState(""); - const locationData = useIPLocationData(); + const locationData = useIPLocationData() || { + timezone: Intl.DateTimeFormat().resolvedOptions().timeZone, + }; const authenticatedData = useAuthenticatedData(); const isMobileWidth = useIsMobileWidth();