cetirizine

An experimental matrix client written in reactjs utilizing tailwind and storybook
git clone git://archive.git.mtrnord.blog/MTRNord/cetirizine.git
Log | Files | Refs | README | LICENSE

commit 073708091d8f38420412a7bfe24b30a0d31032a7
parent bb48b03bec653e247b238828f43188f3e8dd47b4
Author: MTRNord <mtrnord1@gmail.com>
Date:   Sat, 29 Apr 2023 02:17:16 +0200

Fix behavior of dropdown on editor

Diffstat:
Msrc/app/api/api.ts | 23+++++++++++++++++++++--
Msrc/components/input/chat/input.scss | 7+++++--
Msrc/components/input/chat/plugins/ToolbarPlugin.tsx | 24++++++++++++------------
Msrc/pages/MainPage.tsx | 2++
4 files changed, 40 insertions(+), 16 deletions(-)

diff --git a/src/app/api/api.ts b/src/app/api/api.ts @@ -1,5 +1,6 @@ -import { BaseQueryFn, FetchArgs, FetchBaseQueryError, createApi, fetchBaseQuery, retry } from '@reduxjs/toolkit/query/react' +import { BaseQueryFn, FetchArgs, FetchBaseQueryError, createApi, fetchBaseQuery, retry, } from '@reduxjs/toolkit/query/react' import { RootState } from '../store'; + import { ILoginFlows, ILoginParams, ILoginResponse, IRateLimitError, IWellKnown } from './apiTypes'; import { createAction, createReducer } from '@reduxjs/toolkit'; // async function login(baseUrl: string, userId: string, password: string): Promise<MatrixClient> { @@ -63,6 +64,7 @@ const baseQueryWithRetry = retry( export const matrixApi = createApi({ reducerPath: 'matrixApi', baseQuery: baseQueryWithRetry, + refetchOnReconnect: true, tagTypes: ['Login', 'Flows', "WellKnown"], endpoints: (builder) => ({ getWellKnown: builder.query<IWellKnown, undefined>({ @@ -113,6 +115,23 @@ export const matrixApi = createApi({ }, invalidatesTags: ['Login'], }), + sync: builder.query<any[], void>({ + keepUnusedDataFor: 2147483647, + // The query is not relevant here as the data will be provided via streaming updates. + // A queryFn returning an empty array is used, with contents being populated via + // streaming updates below as they are received. + queryFn: () => ({ data: [] }), + async onCacheEntryAdded(_arg, { updateCachedData, cacheEntryRemoved, getState }) { + // TODO: /sync loop + /* + updateCachedData((draft) => { + draft.push(JSON.parse(event.data)) + }) + */ + await cacheEntryRemoved + // Cleanup? + }, + }), }), }); @@ -129,4 +148,4 @@ const rawBaseQuery = (baseUrl: string) => fetchBaseQuery({ // Export hooks for usage in functional components, which are // auto-generated based on the defined endpoints -export const { useLazyGetLoginFlowsQuery, useDoLoginMutation, useLazyGetWellKnownQuery } = matrixApi +export const { useLazyGetLoginFlowsQuery, useDoLoginMutation, useLazyGetWellKnownQuery, useSyncQuery } = matrixApi diff --git a/src/components/input/chat/input.scss b/src/components/input/chat/input.scss @@ -229,8 +229,11 @@ .dropdown { z-index: 5; - display: block; - position: absolute; + display: inline-flex; + flex-direction: column; + //position: absolute; + //position: relative; + margin-bottom: 24px; box-shadow: 0 12px 28px 0 rgba(0, 0, 0, 0.2), 0 2px 4px 0 rgba(0, 0, 0, 0.1), inset 0 0 0 1px rgba(255, 255, 255, 0.5); border-radius: 8px; diff --git a/src/components/input/chat/plugins/ToolbarPlugin.tsx b/src/components/input/chat/plugins/ToolbarPlugin.tsx @@ -292,17 +292,6 @@ function BlockOptionsDropdownList({ const dropDownRef: MutableRefObject<HTMLDivElement | null> = useRef(null); useEffect(() => { - const toolbar = toolbarRef.current; - const dropDown = dropDownRef.current; - - if (toolbar !== null && dropDown !== null) { - const { top, left } = toolbar.getBoundingClientRect(); - dropDown.style.top = `${top + 40}px`; - dropDown.style.left = `${left}px`; - } - }, [dropDownRef, toolbarRef]); - - useEffect(() => { const dropDown = dropDownRef.current; const toolbar = toolbarRef.current; @@ -567,6 +556,17 @@ export default function ToolbarPlugin() { } }, [editor, isLink]); + const [portalContainer, setPortalContainer] = useState<HTMLDivElement | null>(null); + useEffect(() => { + const container = document.getElementsByClassName("editor-container")[0]; + const portalContainer = document.createElement('div'); + container.prepend(portalContainer) + setPortalContainer(portalContainer) + return () => { + container.removeChild(portalContainer) + } + }, []) + return ( <div className="toolbar" ref={toolbarRef}> <button @@ -633,7 +633,7 @@ export default function ToolbarPlugin() { toolbarRef={toolbarRef} setShowBlockOptionsDropDown={setShowBlockOptionsDropDown} />, - document.body + portalContainer!! )} <Divider /> </> diff --git a/src/pages/MainPage.tsx b/src/pages/MainPage.tsx @@ -3,8 +3,10 @@ import Avatar from '../components/avatar/avatar'; import ChatInput from '../components/input/chat/input'; import RoomList from '../components/roomList/roomList'; import './MainPage.scss'; +import { useSyncQuery } from '../app/api/api'; export default function MainPage() { + const { } = useSyncQuery(); // TODO: Calculate rooms and sections within a RTK Query const sections = [ {