Skip to content

Commit

Permalink
Fix/terms of use modal (#57)
Browse files Browse the repository at this point in the history
* fix env override

* add debug

* update astrojs lib

* Update UserArea.tsx

* Update TermsOfUseModal.tsx

* Update Page.tsx

* reconnect automatically
  • Loading branch information
danieleguido authored Nov 23, 2024
1 parent d9f690f commit 895513d
Show file tree
Hide file tree
Showing 8 changed files with 539 additions and 435 deletions.
6 changes: 4 additions & 2 deletions astro.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,11 @@ import react from "@astrojs/react"
import mdx from "@astrojs/mdx"
import dotenv from "dotenv"

// load .env.local file, .env.development file, and .env file
console.log("NODE_ENV:", process.env.NODE_ENV)
dotenv.config({
path: [".env.local", `.env.${process.env.NODE_ENV}`, ".env"],
path: [".env", ".env.local", `.env.${process.env.NODE_ENV}`],
debug: true,
override: true,
})
const WsApiTarget =
process.env.PUBLIC_IMPRESSO_WS_API_HOST ?? "http://localhost"
Expand Down
840 changes: 450 additions & 390 deletions package-lock.json

Large diffs are not rendered by default.

6 changes: 3 additions & 3 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@
},
"dependencies": {
"@astrojs/check": "^0.9.4",
"@astrojs/mdx": "^3.1.8",
"@astrojs/react": "^3.6.2",
"@astrojs/mdx": "^3.1.9",
"@astrojs/react": "^3.6.3",
"@astrolib/seo": "^1.0.0-beta.6",
"@codemirror/lang-python": "^6.1.6",
"@feathersjs/authentication-client": "^5.0.30",
Expand All @@ -34,7 +34,7 @@
"@uiw/codemirror-theme-nord": "^4.23.1",
"@uiw/codemirror-themes": "^4.23.5",
"@uiw/react-codemirror": "^4.23.1",
"astro": "^4.16.7",
"astro": "^4.16.14",
"axios": "^1.7.7",
"bootstrap": "^5.3.3",
"boring-avatars": "^1.11.2",
Expand Down
3 changes: 2 additions & 1 deletion src/components/LoginModal.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,13 +15,14 @@ const LoginModal = () => {
const [error, setError] = useState<FeathersError | null>(null)

const checkCredentials = (credentials: LoginFormPayload) => {
console.debug("[LoginModal] call loginService...")
loginService
.create({
strategy: "local",
...credentials,
})
.then((data) => {
// console.log("loginService.create", data)
console.debug("[LoginModal] loginService.create", data)
setAuthenticatedUser(data.user, data.accessToken)
setView(null)
})
Expand Down
8 changes: 8 additions & 0 deletions src/components/Page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ interface PageProps extends React.HTMLAttributes<HTMLDivElement> {
autoOpenAfterDelay?: boolean
manualOpen?: boolean
onHide?: () => void
onShow?: () => void
}

const Page: React.FC<PageProps> = ({
Expand All @@ -29,6 +30,7 @@ const Page: React.FC<PageProps> = ({
// this is used only when autoOpenAfterDelay is false
manualOpen = false,
onHide,
onShow,
}) => {
const [show, setShow] = useState(false)
const timerRef = useRef<ReturnType<typeof setTimeout>>()
Expand All @@ -49,6 +51,11 @@ const Page: React.FC<PageProps> = ({
)
}, 1000)
}
const handleShow = () => {
if (typeof onShow === "function") {
onShow()
}
}

useEffect(() => {
clearTimeout(timerRef.current)
Expand All @@ -71,6 +78,7 @@ const Page: React.FC<PageProps> = ({
fullscreen={fullscreen}
show={show}
onHide={handleClose}
onShow={handleShow}
backdrop="static"
size={size === "xxl" ? "xl" : size}
keyboard={false}
Expand Down
85 changes: 55 additions & 30 deletions src/components/TermsOfUseModal.tsx
Original file line number Diff line number Diff line change
@@ -1,10 +1,16 @@
import { useCallback, useEffect, useState, type ChangeEvent } from "react"
import {
useCallback,
useEffect,
useRef,
useState,
type ChangeEvent,
} from "react"
import AcceptTermsOfUse from "./AcceptTermsOfUse"
import Page from "./Page"
import Alert from "./Alert"
import { Col, Container, Row } from "react-bootstrap"
import { useBrowserStore, usePersistentStore } from "../store"
import { accountDetailsService } from "../services"
import { termsOfUseService } from "../services"
import { DateTime } from "luxon"
import MarkdownSnippet from "./MarkdownSnippet"
import { BrowserViewTermsOfUse } from "../constants"
Expand All @@ -13,28 +19,10 @@ const TermsOfUseModal: React.FC<{
content: string
autoOpenAfterDelay?: boolean
}> = ({ content, autoOpenAfterDelay = true }) => {
const bottomRef = useRef<HTMLDivElement>(null)
const [isIntersecting, setIsIntersecting] = useState<boolean>(false)

const bottomRef = useCallback((node: HTMLDivElement | null) => {
let observer: IntersectionObserver | null = null
if (node !== null) {
node.textContent = ""
observer = new IntersectionObserver(
([entry]) => {
setIsIntersecting(entry.isIntersecting)
},
{ threshold: 0.5 },
)
observer.observe(node)
}
return () => {
console.debug("[TermsOfUseModal] bottomRef cleanup")
if (node && observer) {
observer.unobserve(node)
}
}
}, [])

const [isBottomRefUnavailable, setIsBottomRefUnavailable] =
useState<boolean>(false)
const [wsStatus, view] = useBrowserStore((state) => [
state.wsStatus,
state.view,
Expand All @@ -56,6 +44,28 @@ const TermsOfUseModal: React.FC<{
const isAcceptedTermsDateValid = acceptedTermsDate
? DateTime.fromISO(acceptedTermsDate).isValid
: false

const onShowHandler = useCallback(() => {
if (!bottomRef.current) {
console.warn(
"[TermsOfUseModal] onShowHandler - bottomRef.current is null!",
)
setIsBottomRefUnavailable(true)
return
}
console.debug("[TermsOfUseModal] onShowHandler create BottomRef")
const observer: IntersectionObserver = new IntersectionObserver(
([entry]) => {
setIsIntersecting(entry.isIntersecting)
},
{ threshold: 0.5 },
)
observer.observe(bottomRef.current)
return () => {
observer.disconnect()
}
}, [])

useEffect(
() => {
if (wsStatus !== "connected") {
Expand All @@ -72,7 +82,8 @@ const TermsOfUseModal: React.FC<{
"[TermsOfUseModal] @useEffect - ws connected, call accountDetails.find() ...",
)
setIsBusy(true)
accountDetailsService

termsOfUseService
.find()
.then((data) => {
console.debug(
Expand Down Expand Up @@ -105,6 +116,7 @@ const TermsOfUseModal: React.FC<{
setView(null)
}
}, [acceptedTermsDate])

useEffect(() => {
if (!enableAcceptTermsButton && isIntersecting) {
setEnableAcceptTermsButton(true)
Expand All @@ -128,7 +140,7 @@ const TermsOfUseModal: React.FC<{
setAcceptedTermsDate(DateTime.now().toISOTime())
setIsBusy(true)

accountDetailsService
termsOfUseService
.patch(null, {
acceptTerms: event.target.checked,
})
Expand All @@ -154,12 +166,19 @@ const TermsOfUseModal: React.FC<{
onHide={() => {
setView(null)
}}
onShow={onShowHandler}
footer={
<AcceptTermsOfUse
checked={isAcceptedTermsDateValid}
onChange={AcceptTermsOfUseOnChangeHandler}
disabled={!enableAcceptTermsButton}
/>
isBottomRefUnavailable ? (
<div className="py-3 text-center w-100 border-top">
Please read carefully our Terms of Use
</div>
) : (
<AcceptTermsOfUse
checked={isAcceptedTermsDateValid}
onChange={AcceptTermsOfUseOnChangeHandler}
disabled={!enableAcceptTermsButton}
/>
)
}
>
<Container>
Expand Down Expand Up @@ -194,6 +213,12 @@ const TermsOfUseModal: React.FC<{
value={content}
onClick={() => setEnableAcceptTermsButton(true)}
/>
{isBottomRefUnavailable ? (
<AcceptTermsOfUse
checked={isAcceptedTermsDateValid}
onChange={AcceptTermsOfUseOnChangeHandler}
/>
) : null}
</div>
<div ref={bottomRef}>&nbsp;</div>
</Row>
Expand Down
8 changes: 4 additions & 4 deletions src/components/UserArea.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ const CustomToggle = forwardRef(
children?: React.ReactNode
onClick: (event: React.MouseEvent<HTMLAnchorElement, MouseEvent>) => {}
},
ref: React.Ref<HTMLAnchorElement>
ref: React.Ref<HTMLAnchorElement>,
) => (
<a
href=""
Expand All @@ -26,7 +26,7 @@ const CustomToggle = forwardRef(
{props.children}
<PageDown className="ms-2" />
</a>
)
),
)

const UserArea = () => {
Expand All @@ -43,7 +43,7 @@ const UserArea = () => {
if (wsStatus !== "connected") {
console.debug(
"[UserArea] @useEffect - ws not connected, current status",
wsStatus
wsStatus,
)
return
}
Expand All @@ -64,7 +64,7 @@ const UserArea = () => {
})
} else {
console.debug(
"[UserArea] @useEffect - ws connected, but no token available. Reset user."
"[UserArea] @useEffect - ws connected, but no token available. Reset user.",
)
setUser(null)
}
Expand Down
18 changes: 13 additions & 5 deletions src/services.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ const socket = io("", {
forceNew: true,
transports: ["websocket"],
})
let timeoutTimer: NodeJS.Timeout | null = null
// print ut socket version
const app = feathers()
app.configure(
Expand All @@ -26,13 +27,20 @@ app.configure(
console.info("[services] socket.io version", socket.io.engine.id)

socket.on("connect_error", (err) => {
console.error("[services] socket.io connection error:", err)
console.error("[services] socket.io connection error:", err.message)
// reconnnect using transports
socket.disconnect()
setWsStatus("closed")
// automatically try to reconnect after 5 seconds
if (timeoutTimer !== null) {
clearTimeout(timeoutTimer)
}
timeoutTimer = setTimeout(() => {
socket.connect()
}, 5000)
})
socket.on("connect_timeout", (timeout) => {
console.error("[services] socket.io connection timeout:", timeout)
socket.on("connect_timeout", (err) => {
console.error("[services] socket.io connection timeout:", err.message)
setWsStatus("closed")
})
socket.on("connect", async () => {
Expand All @@ -47,7 +55,7 @@ socket.on("connect", async () => {
.catch((err) => {
console.warn(
"[services] @connect reAuthenticate failure, skip. Error:",
err,
err.message,
)
return null
})
Expand All @@ -63,5 +71,5 @@ socket.on("reconnect", (attemptNumber) => {
export const versionService = app.service("version")
export const userService = app.service("me")
export const usersService = app.service("users")
export const accountDetailsService = app.service("account-details")
export const termsOfUseService = app.service("terms-of-use")
export const loginService = app.service("authentication")

0 comments on commit 895513d

Please sign in to comment.