web/modal: split context exports to separate file

This commit is contained in:
Tulir Asokan 2024-12-22 14:57:13 +02:00
parent 4160a33edb
commit 202929ae3c
22 changed files with 75 additions and 50 deletions

View file

@ -22,7 +22,7 @@ import WSClient from "./api/wsclient.ts"
import ClientContext from "./ui/ClientContext.ts" import ClientContext from "./ui/ClientContext.ts"
import MainScreen from "./ui/MainScreen.tsx" import MainScreen from "./ui/MainScreen.tsx"
import { LoginScreen, VerificationScreen } from "./ui/login" import { LoginScreen, VerificationScreen } from "./ui/login"
import { LightboxWrapper } from "./ui/modal/Lightbox.tsx" import { LightboxWrapper } from "./ui/modal"
import { useEventAsState } from "./util/eventdispatcher.ts" import { useEventAsState } from "./util/eventdispatcher.ts"
function makeRPCClient(): RPCClient { function makeRPCClient(): RPCClient {

View file

@ -24,7 +24,7 @@ import ClientContext from "./ClientContext.ts"
import MainScreenContext, { MainScreenContextFields } from "./MainScreenContext.ts" import MainScreenContext, { MainScreenContextFields } from "./MainScreenContext.ts"
import StylePreferences from "./StylePreferences.tsx" import StylePreferences from "./StylePreferences.tsx"
import Keybindings from "./keybindings.ts" import Keybindings from "./keybindings.ts"
import { ModalWrapper } from "./modal/Modal.tsx" import { ModalWrapper } from "./modal"
import RightPanel, { RightPanelProps } from "./rightpanel/RightPanel.tsx" import RightPanel, { RightPanelProps } from "./rightpanel/RightPanel.tsx"
import RoomList from "./roomlist/RoomList.tsx" import RoomList from "./roomlist/RoomList.tsx"
import RoomPreview, { RoomPreviewProps } from "./roomview/RoomPreview.tsx" import RoomPreview, { RoomPreviewProps } from "./roomview/RoomPreview.tsx"

View file

@ -33,7 +33,7 @@ import EmojiPicker from "../emojipicker/EmojiPicker.tsx"
import GIFPicker from "../emojipicker/GIFPicker.tsx" import GIFPicker from "../emojipicker/GIFPicker.tsx"
import StickerPicker from "../emojipicker/StickerPicker.tsx" import StickerPicker from "../emojipicker/StickerPicker.tsx"
import { keyToString } from "../keybindings.ts" import { keyToString } from "../keybindings.ts"
import { ModalContext } from "../modal/Modal.tsx" import { ModalContext } from "../modal"
import { useRoomContext } from "../roomview/roomcontext.ts" import { useRoomContext } from "../roomview/roomcontext.ts"
import { ReplyBody } from "../timeline/ReplyBody.tsx" import { ReplyBody } from "../timeline/ReplyBody.tsx"
import type { AutocompleteQuery } from "./Autocompleter.tsx" import type { AutocompleteQuery } from "./Autocompleter.tsx"

View file

@ -20,7 +20,7 @@ import { roomStateGUIDToString } from "@/api/types"
import { CATEGORY_FREQUENTLY_USED, Emoji, PartialEmoji, categories, useFilteredEmojis } from "@/util/emoji" import { CATEGORY_FREQUENTLY_USED, Emoji, PartialEmoji, categories, useFilteredEmojis } from "@/util/emoji"
import { isMobileDevice } from "@/util/ismobile.ts" import { isMobileDevice } from "@/util/ismobile.ts"
import ClientContext from "../ClientContext.ts" import ClientContext from "../ClientContext.ts"
import { ModalCloseContext } from "../modal/Modal.tsx" import { ModalCloseContext } from "../modal"
import { EmojiGroup } from "./EmojiGroup.tsx" import { EmojiGroup } from "./EmojiGroup.tsx"
import renderEmoji from "./renderEmoji.tsx" import renderEmoji from "./renderEmoji.tsx"
import useCategoryUnderline from "./useCategoryUnderline.ts" import useCategoryUnderline from "./useCategoryUnderline.ts"

View file

@ -18,7 +18,7 @@ import { RoomStateStore, usePreference } from "@/api/statestore"
import { MediaMessageEventContent } from "@/api/types" import { MediaMessageEventContent } from "@/api/types"
import { isMobileDevice } from "@/util/ismobile.ts" import { isMobileDevice } from "@/util/ismobile.ts"
import ClientContext from "../ClientContext.ts" import ClientContext from "../ClientContext.ts"
import { ModalCloseContext } from "../modal/Modal.tsx" import { ModalCloseContext } from "../modal"
import { GIF, getTrendingGIFs, searchGIF } from "./gifsource.ts" import { GIF, getTrendingGIFs, searchGIF } from "./gifsource.ts"
import CloseIcon from "@/icons/close.svg?react" import CloseIcon from "@/icons/close.svg?react"
import SearchIcon from "@/icons/search.svg?react" import SearchIcon from "@/icons/search.svg?react"

View file

@ -20,7 +20,7 @@ import { roomStateGUIDToString } from "@/api/types"
import { Emoji, useFilteredEmojis } from "@/util/emoji" import { Emoji, useFilteredEmojis } from "@/util/emoji"
import { isMobileDevice } from "@/util/ismobile.ts" import { isMobileDevice } from "@/util/ismobile.ts"
import ClientContext from "../ClientContext.ts" import ClientContext from "../ClientContext.ts"
import { ModalCloseContext } from "../modal/Modal.tsx" import { ModalCloseContext } from "../modal"
import { EmojiGroup } from "./EmojiGroup.tsx" import { EmojiGroup } from "./EmojiGroup.tsx"
import { MediaPickerProps } from "./GIFPicker.tsx" import { MediaPickerProps } from "./GIFPicker.tsx"
import useCategoryUnderline from "./useCategoryUnderline.ts" import useCategoryUnderline from "./useCategoryUnderline.ts"

View file

@ -13,8 +13,9 @@
// //
// You should have received a copy of the GNU Affero General Public License // You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
import React, { Component, createContext, createRef, useCallback, useLayoutEffect, useState } from "react" import React, { Component, createRef, useCallback, useLayoutEffect, useState } from "react"
import { keyToString } from "../keybindings.ts" import { keyToString } from "../keybindings.ts"
import { LightboxContext, LightboxParams } from "./contexts.ts"
import CloseIcon from "@/icons/close.svg?react" import CloseIcon from "@/icons/close.svg?react"
import DownloadIcon from "@/icons/download.svg?react" import DownloadIcon from "@/icons/download.svg?react"
import RotateLeftIcon from "@/icons/rotate-left.svg?react" import RotateLeftIcon from "@/icons/rotate-left.svg?react"
@ -25,17 +26,7 @@ import "./Lightbox.css"
const isTouchDevice = window.ontouchstart !== undefined const isTouchDevice = window.ontouchstart !== undefined
export interface LightboxParams { const LightboxWrapper = ({ children }: { children: React.ReactNode }) => {
src: string
alt: string
}
export type OpenLightboxType = (params: LightboxParams | React.MouseEvent<HTMLImageElement>) => void
export const LightboxContext = createContext<OpenLightboxType>(() =>
console.error("Tried to open lightbox without being inside context"))
export const LightboxWrapper = ({ children }: { children: React.ReactNode }) => {
const [params, setParams] = useState<LightboxParams | null>(null) const [params, setParams] = useState<LightboxParams | null>(null)
const onOpen = useCallback((params: LightboxParams | React.MouseEvent<HTMLImageElement>) => { const onOpen = useCallback((params: LightboxParams | React.MouseEvent<HTMLImageElement>) => {
if ((params as React.MouseEvent).target) { if ((params as React.MouseEvent).target) {
@ -224,3 +215,5 @@ export class Lightbox extends Component<LightboxProps> {
</div> </div>
} }
} }
export default LightboxWrapper

View file

@ -13,25 +13,10 @@
// //
// You should have received a copy of the GNU Affero General Public License // You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>. // along with this program. If not, see <https://www.gnu.org/licenses/>.
import React, { JSX, createContext, useCallback, useLayoutEffect, useReducer, useRef } from "react" import React, { JSX, useCallback, useLayoutEffect, useReducer, useRef } from "react"
import { ModalCloseContext, ModalContext, ModalState } from "./contexts.ts"
export interface ModalState { const ModalWrapper = ({ children }: { children: React.ReactNode }) => {
content: JSX.Element
dimmed?: boolean
boxed?: boolean
boxClass?: string
innerBoxClass?: string
onClose?: () => void
}
type openModal = (state: ModalState) => void
export const ModalContext = createContext<openModal>(() =>
console.error("Tried to open modal without being inside context"))
export const ModalCloseContext = createContext<() => void>(() => {})
export const ModalWrapper = ({ children }: { children: React.ReactNode }) => {
const [state, setState] = useReducer((prevState: ModalState | null, newState: ModalState | null) => { const [state, setState] = useReducer((prevState: ModalState | null, newState: ModalState | null) => {
prevState?.onClose?.() prevState?.onClose?.()
return newState return newState
@ -98,3 +83,5 @@ export const ModalWrapper = ({ children }: { children: React.ReactNode }) => {
{modal} {modal}
</ModalContext> </ModalContext>
} }
export default ModalWrapper

View file

@ -0,0 +1,42 @@
// gomuks - A Matrix client written in Go.
// Copyright (C) 2024 Tulir Asokan
//
// This program is free software: you can redistribute it and/or modify
// it under the terms of the GNU Affero General Public License as published by
// the Free Software Foundation, either version 3 of the License, or
// (at your option) any later version.
//
// This program is distributed in the hope that it will be useful,
// but WITHOUT ANY WARRANTY; without even the implied warranty of
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
// GNU Affero General Public License for more details.
//
// You should have received a copy of the GNU Affero General Public License
// along with this program. If not, see <https://www.gnu.org/licenses/>.
import React, { JSX, createContext } from "react"
export interface LightboxParams {
src: string
alt: string
}
export type OpenLightboxType = (params: LightboxParams | React.MouseEvent<HTMLImageElement>) => void
export const LightboxContext = createContext<OpenLightboxType>(() =>
console.error("Tried to open lightbox without being inside context"))
export interface ModalState {
content: JSX.Element
dimmed?: boolean
boxed?: boolean
boxClass?: string
innerBoxClass?: string
onClose?: () => void
}
type openModal = (state: ModalState) => void
export const ModalContext = createContext<openModal>(() =>
console.error("Tried to open modal without being inside context"))
export const ModalCloseContext = createContext<() => void>(() => {})

View file

@ -0,0 +1,3 @@
export * from "./contexts.ts"
export { default as ModalWrapper } from "./Modal.tsx"
export { default as LightboxWrapper } from "./Lightbox.tsx"

View file

@ -20,7 +20,7 @@ import { useRoomMember } from "@/api/statestore"
import { MemberEventContent, UserID, UserProfile } from "@/api/types" import { MemberEventContent, UserID, UserProfile } from "@/api/types"
import { getLocalpart } from "@/util/validation.ts" import { getLocalpart } from "@/util/validation.ts"
import ClientContext from "../ClientContext.ts" import ClientContext from "../ClientContext.ts"
import { LightboxContext } from "../modal/Lightbox.tsx" import { LightboxContext } from "../modal"
import { RoomContext } from "../roomview/roomcontext.ts" import { RoomContext } from "../roomview/roomcontext.ts"
import DeviceList from "./UserInfoDeviceList.tsx" import DeviceList from "./UserInfoDeviceList.tsx"
import UserInfoError from "./UserInfoError.tsx" import UserInfoError from "./UserInfoError.tsx"

View file

@ -21,7 +21,7 @@ import { RoomID, RoomSummary } from "@/api/types"
import { getDisplayname, getServerName } from "@/util/validation.ts" import { getDisplayname, getServerName } from "@/util/validation.ts"
import ClientContext from "../ClientContext.ts" import ClientContext from "../ClientContext.ts"
import MainScreenContext from "../MainScreenContext.ts" import MainScreenContext from "../MainScreenContext.ts"
import { LightboxContext } from "../modal/Lightbox.tsx" import { LightboxContext } from "../modal"
import MutualRooms from "../rightpanel/UserInfoMutualRooms.tsx" import MutualRooms from "../rightpanel/UserInfoMutualRooms.tsx"
import ErrorIcon from "@/icons/error.svg?react" import ErrorIcon from "@/icons/error.svg?react"
import GroupIcon from "@/icons/group.svg?react" import GroupIcon from "@/icons/group.svg?react"

View file

@ -18,8 +18,8 @@ import { getRoomAvatarURL } from "@/api/media.ts"
import { RoomStateStore } from "@/api/statestore" import { RoomStateStore } from "@/api/statestore"
import { useEventAsState } from "@/util/eventdispatcher.ts" import { useEventAsState } from "@/util/eventdispatcher.ts"
import MainScreenContext from "../MainScreenContext.ts" import MainScreenContext from "../MainScreenContext.ts"
import { LightboxContext } from "../modal/Lightbox.tsx" import { LightboxContext } from "../modal"
import { ModalContext } from "../modal/Modal.tsx" import { ModalContext } from "../modal"
import SettingsView from "../settings/SettingsView.tsx" import SettingsView from "../settings/SettingsView.tsx"
import BackIcon from "@/icons/back.svg?react" import BackIcon from "@/icons/back.svg?react"
import PeopleIcon from "@/icons/group.svg?react" import PeopleIcon from "@/icons/group.svg?react"

View file

@ -29,8 +29,8 @@ import {
import { useEventAsState } from "@/util/eventdispatcher.ts" import { useEventAsState } from "@/util/eventdispatcher.ts"
import useEvent from "@/util/useEvent.ts" import useEvent from "@/util/useEvent.ts"
import ClientContext from "../ClientContext.ts" import ClientContext from "../ClientContext.ts"
import { LightboxContext } from "../modal/Lightbox.tsx" import { LightboxContext } from "../modal"
import { ModalCloseContext } from "../modal/Modal.tsx" import { ModalCloseContext } from "../modal"
import JSONView from "../util/JSONView.tsx" import JSONView from "../util/JSONView.tsx"
import Toggle from "../util/Toggle.tsx" import Toggle from "../util/Toggle.tsx"
import CloseIcon from "@/icons/close.svg?react" import CloseIcon from "@/icons/close.svg?react"

View file

@ -21,7 +21,7 @@ import { isMobileDevice } from "@/util/ismobile.ts"
import { getDisplayname, isEventID } from "@/util/validation.ts" import { getDisplayname, isEventID } from "@/util/validation.ts"
import ClientContext from "../ClientContext.ts" import ClientContext from "../ClientContext.ts"
import MainScreenContext from "../MainScreenContext.ts" import MainScreenContext from "../MainScreenContext.ts"
import { ModalContext } from "../modal/Modal.tsx" import { ModalContext } from "../modal"
import { useRoomContext } from "../roomview/roomcontext.ts" import { useRoomContext } from "../roomview/roomcontext.ts"
import ReadReceipts from "./ReadReceipts.tsx" import ReadReceipts from "./ReadReceipts.tsx"
import { ReplyIDBody } from "./ReplyBody.tsx" import { ReplyIDBody } from "./ReplyBody.tsx"

View file

@ -19,7 +19,7 @@ import { RoomStateStore, usePreference } from "@/api/statestore"
import { MemDBEvent, URLPreview } from "@/api/types" import { MemDBEvent, URLPreview } from "@/api/types"
import { ImageContainerSize, calculateMediaSize } from "@/util/mediasize" import { ImageContainerSize, calculateMediaSize } from "@/util/mediasize"
import ClientContext from "../ClientContext" import ClientContext from "../ClientContext"
import { LightboxContext } from "../modal/Lightbox.tsx" import { LightboxContext } from "../modal"
import "./URLPreviews.css" import "./URLPreviews.css"
const URLPreviews = ({ event, room }: { const URLPreviews = ({ event, room }: {

View file

@ -16,7 +16,7 @@
import React, { use } from "react" import React, { use } from "react"
import { getAvatarURL } from "@/api/media.ts" import { getAvatarURL } from "@/api/media.ts"
import { MemberEventContent, UserID } from "@/api/types" import { MemberEventContent, UserID } from "@/api/types"
import { LightboxContext } from "../../modal/Lightbox.tsx" import { LightboxContext } from "../../modal"
import EventContentProps from "./props.ts" import EventContentProps from "./props.ts"
function useChangeDescription( function useChangeDescription(

View file

@ -17,7 +17,7 @@ import { JSX, use } from "react"
import { getRoomAvatarURL } from "@/api/media.ts" import { getRoomAvatarURL } from "@/api/media.ts"
import { ContentURI, RoomAvatarEventContent } from "@/api/types" import { ContentURI, RoomAvatarEventContent } from "@/api/types"
import { ensureString } from "@/util/validation.ts" import { ensureString } from "@/util/validation.ts"
import { LightboxContext } from "../../modal/Lightbox.tsx" import { LightboxContext } from "../../modal"
import EventContentProps from "./props.ts" import EventContentProps from "./props.ts"
const RoomAvatarBody = ({ event, sender, room }: EventContentProps) => { const RoomAvatarBody = ({ event, sender, room }: EventContentProps) => {

View file

@ -17,7 +17,7 @@ import React, { CSSProperties, JSX, use } from "react"
import { getEncryptedMediaURL, getMediaURL } from "@/api/media.ts" import { getEncryptedMediaURL, getMediaURL } from "@/api/media.ts"
import type { EventType, MediaMessageEventContent } from "@/api/types" import type { EventType, MediaMessageEventContent } from "@/api/types"
import { ImageContainerSize, calculateMediaSize, defaultVideoContainerSize } from "@/util/mediasize.ts" import { ImageContainerSize, calculateMediaSize, defaultVideoContainerSize } from "@/util/mediasize.ts"
import { LightboxContext } from "../../modal/Lightbox.tsx" import { LightboxContext } from "../../modal"
import DownloadIcon from "@/icons/download.svg?react" import DownloadIcon from "@/icons/download.svg?react"
export const useMediaContent = ( export const useMediaContent = (

View file

@ -16,7 +16,7 @@
import React, { use, useState } from "react" import React, { use, useState } from "react"
import { MemDBEvent } from "@/api/types" import { MemDBEvent } from "@/api/types"
import { isMobileDevice } from "@/util/ismobile.ts" import { isMobileDevice } from "@/util/ismobile.ts"
import { ModalCloseContext } from "../../modal/Modal.tsx" import { ModalCloseContext } from "../../modal"
import TimelineEvent from "../TimelineEvent.tsx" import TimelineEvent from "../TimelineEvent.tsx"
interface ConfirmWithMessageProps { interface ConfirmWithMessageProps {

View file

@ -19,7 +19,7 @@ import { MemDBEvent } from "@/api/types"
import { emojiToReactionContent } from "@/util/emoji" import { emojiToReactionContent } from "@/util/emoji"
import { useEventAsState } from "@/util/eventdispatcher.ts" import { useEventAsState } from "@/util/eventdispatcher.ts"
import EmojiPicker from "../../emojipicker/EmojiPicker.tsx" import EmojiPicker from "../../emojipicker/EmojiPicker.tsx"
import { ModalCloseContext, ModalContext } from "../../modal/Modal.tsx" import { ModalCloseContext, ModalContext } from "../../modal"
import { RoomContextData } from "../../roomview/roomcontext.ts" import { RoomContextData } from "../../roomview/roomcontext.ts"
import { EventExtraMenu } from "./EventMenu.tsx" import { EventExtraMenu } from "./EventMenu.tsx"
import { getEncryption, getModalStyleFromButton, getPending, getPowerLevels } from "./util.ts" import { getEncryption, getModalStyleFromButton, getPending, getPowerLevels } from "./util.ts"

View file

@ -17,7 +17,7 @@ import { use } from "react"
import Client from "@/api/client.ts" import Client from "@/api/client.ts"
import { useRoomState } from "@/api/statestore" import { useRoomState } from "@/api/statestore"
import { MemDBEvent } from "@/api/types" import { MemDBEvent } from "@/api/types"
import { ModalCloseContext, ModalContext } from "../../modal/Modal.tsx" import { ModalCloseContext, ModalContext } from "../../modal"
import { RoomContext, RoomContextData } from "../../roomview/roomcontext.ts" import { RoomContext, RoomContextData } from "../../roomview/roomcontext.ts"
import JSONView from "../../util/JSONView.tsx" import JSONView from "../../util/JSONView.tsx"
import ConfirmWithMessageModal from "./ConfirmWithMessageModal.tsx" import ConfirmWithMessageModal from "./ConfirmWithMessageModal.tsx"