Skip to content

Commit

Permalink
Set users timezone correctly in add to calendar button
Browse files Browse the repository at this point in the history
  • Loading branch information
blopker committed Jan 9, 2025
1 parent 532baeb commit ca6aac6
Show file tree
Hide file tree
Showing 9 changed files with 60 additions and 39 deletions.
6 changes: 3 additions & 3 deletions assets/js/app.js → assets/js/app.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,12 +4,12 @@ import copyToClipboard from "./libs/copyToClipboard"
import emailSpellChecker from "./libs/emailSpellCheck"
import loginChannel from "./libs/loginChannel"
import shadowfill from "./libs/shadowfill"
import timezoneDetect from "./libs/timezone"
import { setTimeZoneCookie } from "./libs/timezone"

import logger from "./libs/logger"

globalThis.dismiss_alert = (e) => {
e.closest(".alert-dismissible").remove()
e.closest(".alert-dismissible")?.remove()
}

// Fix for instagram browser errors in sentry
Expand All @@ -18,7 +18,7 @@ globalThis._AutofillCallbackHandler =
globalThis._AutofillCallbackHandler || (() => {})

components()
timezoneDetect()
setTimeZoneCookie()
loginChannel()
copyToClipboard()

Expand Down
6 changes: 3 additions & 3 deletions assets/js/components/AddToCalendarButton.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import { convertISOToHHMM, getDateFromISOString } from "@/libs/time"

import { getTimeZone } from "@/libs/timezone"
function AddToCalendarButton(props: {
name: string
calLink: string
Expand All @@ -21,7 +21,7 @@ function AddToCalendarButton(props: {
const calLink = () => `${props.calLink}?r=cal_link`.replaceAll('"', "")

// console.log(props)
const debug = window.TOTEM_DATA.debug ? "true" : "false"
const debug = globalThis.TOTEM_DATA.debug ? "true" : "false"
const el = `<add-to-calendar-button
styleLight="--btn-shadow:none; --btn-shadow-hover:none"
inline
Expand All @@ -36,7 +36,7 @@ function AddToCalendarButton(props: {
endDate="${endDate()}"
startTime="${startTime()}"
endTime="${endTime()}"
timeZone="UTC"></add-to-calendar-button>`
timeZone="${getTimeZone()}"></add-to-calendar-button>`
// eslint-disable-next-line solid/no-innerhtml
return <div innerHTML={el} />
}
Expand Down
12 changes: 6 additions & 6 deletions assets/js/components/eventCalendar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { totemCirclesApiUpcomingEvents } from "@/client"
import Calendar from "@rnwonder/solid-date-picker/calendar"
import "@rnwonder/solid-date-picker/dist/style.css"
import { createQuery } from "@tanstack/solid-query"
import { createSignal, JSX, JSXElement, Suspense } from "solid-js"
import { type JSX, type JSXElement, Suspense, createSignal } from "solid-js"
import "./eventCalendar.css"

function DetailBox(props: { children: JSX.Element }) {
Expand All @@ -17,7 +17,7 @@ function Loading() {
return (
<DetailBox>
<div class="text-center">
<div class="spinner-border" role="status">
<div class="spinner-border">
<span class="loading loading-spinner loading-lg" />
</div>
</div>
Expand All @@ -26,8 +26,8 @@ function Loading() {
}

const EventCalendar = (props: {
spaceid?: string
eventid?: string
spaceid: string
eventid: string
children?: JSXElement
}) => {
const [month, setMonth] = createSignal(new Date().getMonth() + 1)
Expand All @@ -37,15 +37,15 @@ const EventCalendar = (props: {
queryFn: async () => {
const response = await totemCirclesApiUpcomingEvents({
query: {
space_slug: props.spaceid!,
space_slug: props.spaceid,
month: month(),
year: year(),
},
})
if (response.error) {
throw new Error(response.error as string)
}
return response.data!
return response.data
},
throwOnError: true,
}))
Expand Down
9 changes: 5 additions & 4 deletions assets/js/components/index.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import { QueryClient, QueryClientProvider } from "@tanstack/solid-query"
import { customElement, noShadowDOM } from "solid-element"
import type { Component, JSXElement } from "solid-js"
import type { JSXElement, ValidComponent } from "solid-js"
import { Dynamic } from "solid-js/web"
import Avatar from "./avatar"
import Circles from "./circles"
import DetailSidebar from "./detailSidebar"
Expand All @@ -11,7 +12,7 @@ import PromptSearch from "./promptSearch"
import Time from "./time"
import Tooltip from "./tooltip"

type WCComponent = Component & {
type WCComponent = ValidComponent & {
tagName: string
propsDefault: Record<string, string | number | null | JSXElement>
}
Expand Down Expand Up @@ -42,7 +43,7 @@ const queryClient = new QueryClient({})
function customElementWC(
name: string,
propDefaults: CustomElementProps,
Components: Component<CustomElementProps>
Components: ValidComponent
) {
customElement(
name,
Expand All @@ -67,7 +68,7 @@ function customElementWC(
return (
<QueryClientProvider client={queryClient}>
<ErrorBoundary>
<Components {...props} />
<Dynamic component={Components} {...props} />
</ErrorBoundary>
</QueryClientProvider>
)
Expand Down
27 changes: 13 additions & 14 deletions assets/js/components/promptSearch.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
import uFuzzy from "@leeoniya/ufuzzy"
import { For, JSXElement, createEffect, createSignal, onMount } from "solid-js"
import {
For,
type JSXElement,
createEffect,
createSignal,
onMount,
} from "solid-js"

interface TagProps {
onClick: (tag: string) => void
Expand Down Expand Up @@ -45,32 +51,25 @@ function PromptSearch(props: { dataid?: string; children?: JSXElement }) {

onMount(() => {
const data = JSON.parse(
document.getElementById(props.dataid!)!.textContent!
document.getElementById(props.dataid ?? "")?.textContent ?? "[]"
) as PromptItem[]
setData(data)
})

const uf = new uFuzzy()
const tags = () => {
return [
...new Set(
data()
.map((r) => r.tags)
.flat()
),
].sort()
return [...new Set(data().flatMap((r) => r.tags))].sort()
}
const haystack = () => {
return data().map((r) => `${r.prompt} ${r.tags.join(" ")}`)
}
const items = () => {
if (search() === "") {
return data()
} else {
const [idxs, _info, order] = uf.search(haystack(), search(), 0)
if (order) {
return order.map((i: number) => idxs.map((i: number) => data()[i])[i])
}
}
const [idxs, _info, order] = uf.search(haystack(), search(), 0)
if (order) {
return order.map((i: number) => idxs.map((i: number) => data()[i])[i])
}
}

Expand Down
19 changes: 17 additions & 2 deletions assets/js/libs/timezone.js
Original file line number Diff line number Diff line change
@@ -1,11 +1,26 @@
export default function () {
function setTimeZoneCookie() {
// Timezone settings. See TimezoneMiddleware in utils/middleware.py
// If timezone isn't set in cookies, set it. Pages can force a reload if they need to.
const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone // e.g. "America/New_York"
const timezone = getTimeZone() // e.g. "America/New_York"
const hasTimezone = globalThis.document.cookie
.split(";")
.some((item) => item.trim().startsWith("totem_timezone="))
if (timezone && !hasTimezone) {
globalThis.document.cookie = `totem_timezone=${timezone}; SameSite=Strict; Secure; path=/; max-age=31536000`
}
}

function getTimeZone() {
try {
if (Intl?.DateTimeFormat) {
const timeZone = Intl.DateTimeFormat().resolvedOptions().timeZone
return timeZone || "UTC" // fallback to UTC if timeZone is undefined
}
return "UTC" // fallback if Intl.DateTimeFormat isn't available
} catch (error) {
console.error("Error getting timezone:", error)
return "UTC" // fallback in case of any errors
}
}

export { setTimeZoneCookie, getTimeZone }
6 changes: 3 additions & 3 deletions build.mjs
Original file line number Diff line number Diff line change
@@ -1,13 +1,13 @@
#!/usr/bin/env node
import * as esbuild from "esbuild"
import { solidPlugin } from "esbuild-plugin-solid"
import fs from "node:fs"
import process from "node:process"
import * as esbuild from "esbuild"
import { solidPlugin } from "esbuild-plugin-solid"

const arg = process.argv[2]

const options = {
entryPoints: ["assets/js/app.js", "assets/js/social.ts"],
entryPoints: ["assets/js/app.ts", "assets/js/social.ts"],
bundle: true,
minify: true,
metafile: true,
Expand Down
9 changes: 6 additions & 3 deletions global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,15 @@ declare namespace JSX {
}
}

// add TOTEM_DATA to window
declare interface Window {
TOTEM_DATA: {
declare global {
function dismiss_alert(e: HTMLElement): void
function _AutofillCallbackHandler(): void
var TOTEM_DATA: {
debug: boolean
csrf_token: string
is_authenticated: boolean
reload_on_login: boolean
}
}

export {}
5 changes: 4 additions & 1 deletion totem/circles/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
from ninja.pagination import paginate
from ninja.params.functions import Query

from totem.users.models import User
from totem.users.schemas import UserSchema

from .filters import all_upcoming_recommended_events, events_by_month
Expand Down Expand Up @@ -115,13 +116,15 @@ class EventDetailSchema(Schema):
url_name="event_detail",
)
def event_detail(request, event_slug):
user: User = request.user
event = get_object_or_404(CircleEvent, slug=event_slug)
space = event.circle
attending = event.attendees.filter(pk=request.user.pk).exists()
start = event.start
join_url = event.join_url(request.user) if attending else None
subscribed = space.subscribed.contains(request.user) if request.user.is_authenticated else None
ended = event.ended()
tz = user.timezone if user.is_authenticated else "UTC"
if attending and not ended:
attendees = [a for a in event.attendees.all()]
else:
Expand All @@ -148,7 +151,7 @@ def event_detail(request, event_slug):
calLink=event.cal_link(),
subscribe_url=reverse("circles:subscribe", kwargs={"slug": space.slug}),
subscribed=subscribed,
user_timezone="UTC",
user_timezone=str(tz),
)


Expand Down

0 comments on commit ca6aac6

Please sign in to comment.