a tool for shared writing and social publishing
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

wire up undo/redo buttons

+43 -16
+38 -15
components/Pages/index.tsx
··· 42 42 import { Watermark } from "components/Watermark"; 43 43 import { scrollIntoViewIfNeeded } from "src/utils/scrollIntoViewIfNeeded"; 44 44 import { LoginButton } from "components/LoginButton"; 45 + import { useUndoState } from "src/undoManager"; 46 + import { useIsMobile } from "src/hooks/isMobile"; 45 47 46 48 export function Pages(props: { rootPage: string }) { 47 49 let rootPage = useEntity(props.rootPage, "root/page")[0]; ··· 249 251 ); 250 252 }; 251 253 252 - const PageOptions = (props: { 253 - entityID: string; 254 - first: boolean | undefined; 255 - }) => { 256 - let greyButtonStyle = 257 - "pt-[2px] h-5 w-5 p-0.5 mx-auto bg-border text-bg-page sm:rounded-r-md sm:rounded-l-none rounded-b-md hover:bg-accent-1 hover:text-accent-2"; 258 - let whiteButtonStyle = ` 254 + let greyButtonStyle = 255 + "pt-[2px] h-5 w-5 p-0.5 mx-auto bg-border text-bg-page sm:rounded-r-md sm:rounded-l-none rounded-b-md hover:bg-accent-1 hover:text-accent-2"; 256 + let whiteButtonStyle = ` 259 257 pageOptionsTrigger 260 258 shrink-0 261 259 bg-bg-page text-border 262 260 outline-none border sm:border-l-0 border-t-1 border-border sm:rounded-r-md sm:rounded-l-none rounded-b-md 263 261 hover:shadow-[0_1px_0_theme(colors.border)_inset,_0_-1px_0_theme(colors.border)_inset,_-1px_0_0_theme(colors.border)_inset] 264 262 flex items-center justify-center`; 265 - 263 + const PageOptions = (props: { 264 + entityID: string; 265 + first: boolean | undefined; 266 + }) => { 266 267 return ( 267 268 <div className=" z-10 w-fit absolute sm:top-3 sm:-right-[19px] top-0 right-3 flex sm:flex-col flex-row-reverse gap-1 items-start"> 268 269 {!props.first && ( ··· 280 281 first={!!props.first} 281 282 buttonStyle={whiteButtonStyle} 282 283 /> 284 + <UndoButtons /> 285 + </div> 286 + ); 287 + }; 288 + 289 + const UndoButtons = () => { 290 + let undoState = useUndoState(); 291 + let { undoManager } = useReplicache(); 292 + return ( 293 + <Media mobile> 283 294 <div className="gap-1 flex sm:flex-col"> 284 - <button className={`${whiteButtonStyle} h-5 w-5 p-0.5`}> 285 - <UndoTiny /> 286 - </button> 287 - <button className={`${whiteButtonStyle} h-5 w-5 p-0.5`}> 288 - <RedoTiny /> 289 - </button> 295 + {undoState.canUndo && ( 296 + <button 297 + className={`${whiteButtonStyle} h-5 w-5 p-0.5`} 298 + onClick={() => undoManager.undo()} 299 + > 300 + <UndoTiny /> 301 + </button> 302 + )} 303 + {undoState.canRedo ? ( 304 + <button 305 + className={`${whiteButtonStyle} h-5 w-5 p-0.5`} 306 + onClick={() => undoManager.undo()} 307 + > 308 + <RedoTiny /> 309 + </button> 310 + ) : ( 311 + <div className="h-5 w-5 p-0.5" /> 312 + )} 290 313 </div> 291 - </div> 314 + </Media> 292 315 ); 293 316 }; 294 317
+5 -1
src/undoManager.ts
··· 1 1 import { UndoManager as RociUndoManager } from "@rocicorp/undo"; 2 + import { create } from "zustand"; 2 3 3 4 export type UndoManager = ReturnType<typeof createUndoManager>; 5 + export const useUndoState = create(() => ({ canUndo: false, canRedo: false })); 4 6 export const createUndoManager = () => { 5 7 let isGrouping = false; 6 8 let undoManager = new RociUndoManager({ 7 - onChange: (state) => {}, 9 + onChange: (state) => { 10 + useUndoState.setState(state); 11 + }, 8 12 }); 9 13 let um = { 10 14 add: (args: {