mirror of
https://github.com/docmost/docmost.git
synced 2025-11-19 05:11:16 +10:00
feat: edit mode preference (#666)
* lock/unlock pages * remove using isLocked column - add default page edit state preference * * Move state management to editors (avoids flickers on edit mode switch) * Rename variables * Add strings to translation file * Memoize components in page component * Fix title editor sending update request on editable state change * fixed errors merging main * Fix embed view in read-only mode * remove unused line * sync * fix responsiveness on mobile --------- Co-authored-by: Philipinho <16838612+Philipinho@users.noreply.github.com>
This commit is contained in:
@ -32,7 +32,7 @@ const schema = z.object({
|
||||
|
||||
export default function EmbedView(props: NodeViewProps) {
|
||||
const { t } = useTranslation();
|
||||
const { node, selected, updateAttributes } = props;
|
||||
const { node, selected, updateAttributes, editor } = props;
|
||||
const { src, provider } = node.attrs;
|
||||
|
||||
const embedUrl = useMemo(() => {
|
||||
@ -50,6 +50,10 @@ export default function EmbedView(props: NodeViewProps) {
|
||||
});
|
||||
|
||||
async function onSubmit(data: { url: string }) {
|
||||
if (!editor.isEditable) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (provider) {
|
||||
const embedProvider = getEmbedProviderById(provider);
|
||||
if (embedProvider.id === "iframe") {
|
||||
@ -85,7 +89,13 @@ export default function EmbedView(props: NodeViewProps) {
|
||||
</AspectRatio>
|
||||
</>
|
||||
) : (
|
||||
<Popover width={300} position="bottom" withArrow shadow="md">
|
||||
<Popover
|
||||
width={300}
|
||||
position="bottom"
|
||||
withArrow
|
||||
shadow="md"
|
||||
disabled={!editor.isEditable}
|
||||
>
|
||||
<Popover.Target>
|
||||
<Card
|
||||
radius="md"
|
||||
|
||||
@ -42,7 +42,11 @@ export function FullEditor({
|
||||
spaceSlug={spaceSlug}
|
||||
editable={editable}
|
||||
/>
|
||||
<MemoizedPageEditor pageId={pageId} editable={editable} content={content} />
|
||||
<MemoizedPageEditor
|
||||
pageId={pageId}
|
||||
editable={editable}
|
||||
content={content}
|
||||
/>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
|
||||
@ -52,6 +52,7 @@ import { IPage } from "@/features/page/types/page.types.ts";
|
||||
import { useParams } from "react-router-dom";
|
||||
import { extractPageSlugId } from "@/lib";
|
||||
import { FIVE_MINUTES } from "@/lib/constants.ts";
|
||||
import { PageEditMode } from "@/features/user/types/user.types.ts";
|
||||
import { jwtDecode } from "jwt-decode";
|
||||
|
||||
interface PageEditorProps {
|
||||
@ -85,6 +86,8 @@ export default function PageEditor({
|
||||
const [isCollabReady, setIsCollabReady] = useState(false);
|
||||
const { pageSlug } = useParams();
|
||||
const slugId = extractPageSlugId(pageSlug);
|
||||
const userPageEditMode =
|
||||
currentUser?.user?.settings?.preferences?.pageEditMode ?? PageEditMode.Edit;
|
||||
|
||||
const localProvider = useMemo(() => {
|
||||
const provider = new IndexeddbPersistence(documentName, ydoc);
|
||||
@ -290,6 +293,17 @@ export default function PageEditor({
|
||||
return () => clearTimeout(collabReadyTimeout);
|
||||
}, [isRemoteSynced, isLocalSynced, remoteProvider?.status]);
|
||||
|
||||
useEffect(() => {
|
||||
// honor user default page edit mode preference
|
||||
if (userPageEditMode && editor && editable && isSynced) {
|
||||
if (userPageEditMode === PageEditMode.Edit) {
|
||||
editor.setEditable(true);
|
||||
} else if (userPageEditMode === PageEditMode.Read) {
|
||||
editor.setEditable(false);
|
||||
}
|
||||
}
|
||||
}, [userPageEditMode, editor, editable, isSynced]);
|
||||
|
||||
return isCollabReady ? (
|
||||
<div>
|
||||
<div ref={menuContainerRef}>
|
||||
|
||||
@ -21,6 +21,8 @@ import { useTranslation } from "react-i18next";
|
||||
import EmojiCommand from "@/features/editor/extensions/emoji-command.ts";
|
||||
import { UpdateEvent } from "@/features/websocket/types";
|
||||
import localEmitter from "@/lib/local-emitter.ts";
|
||||
import { currentUserAtom } from "@/features/user/atoms/current-user-atom.ts";
|
||||
import { PageEditMode } from "@/features/user/types/user.types.ts";
|
||||
|
||||
export interface TitleEditorProps {
|
||||
pageId: string;
|
||||
@ -44,6 +46,9 @@ export function TitleEditor({
|
||||
const emit = useQueryEmit();
|
||||
const navigate = useNavigate();
|
||||
const [activePageId, setActivePageId] = useState(pageId);
|
||||
const [currentUser] = useAtom(currentUserAtom);
|
||||
const userPageEditMode =
|
||||
currentUser?.user?.settings?.preferences?.pageEditMode ?? PageEditMode.Edit;
|
||||
|
||||
const titleEditor = useEditor({
|
||||
extensions: [
|
||||
@ -136,7 +141,18 @@ export function TitleEditor({
|
||||
};
|
||||
}, [pageId]);
|
||||
|
||||
function handleTitleKeyDown(event) {
|
||||
useEffect(() => {
|
||||
// honor user default page edit mode preference
|
||||
if (userPageEditMode && titleEditor && editable) {
|
||||
if (userPageEditMode === PageEditMode.Edit) {
|
||||
titleEditor.setEditable(true);
|
||||
} else if (userPageEditMode === PageEditMode.Read) {
|
||||
titleEditor.setEditable(false);
|
||||
}
|
||||
}
|
||||
}, [userPageEditMode, titleEditor, editable]);
|
||||
|
||||
function handleTitleKeyDown(event: any) {
|
||||
if (!titleEditor || !pageEditor || event.shiftKey) return;
|
||||
|
||||
const { key } = event;
|
||||
|
||||
Reference in New Issue
Block a user