collaborative-ui
Version:
React component library for building real-time collaborative editing applications.
117 lines (116 loc) • 6.55 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
exports.JsonCrdtLog = void 0;
const tslib_1 = require("tslib");
const Paper_1 = require("nice-ui/lib/4-card/Paper");
const Split_1 = require("nice-ui/lib/3-list-item/Split");
const Flex_1 = require("nice-ui/lib/3-list-item/Flex");
const Space_1 = require("nice-ui/lib/3-list-item/Space");
const MiniTitle_1 = require("nice-ui/lib/3-list-item/MiniTitle");
const RunningBackground_1 = require("nice-ui/lib/3-list-item/RunningBackground");
const useBehaviorSubject_1 = require("nice-ui/lib/hooks/useBehaviorSubject");
const context_1 = require("nice-ui/lib/7-fullscreen/ToastCardManager/context");
const React = tslib_1.__importStar(require("react"));
const nano_theme_1 = require("nano-theme");
const use_t_1 = require("use-t");
const LogicalTimestamp_1 = require("../LogicalTimestamp");
const JsonCrdtLogState_1 = require("./JsonCrdtLogState");
const ViewSelect_1 = require("./ViewSelect");
const JsonCrdtModel_1 = require("../JsonCrdtModel");
const Timeline_1 = require("./Timeline");
const context_2 = require("./context");
const PlaybackToolbar_1 = require("./PlaybackToolbar");
const JsonCrdtLogTextual_1 = require("./JsonCrdtLogTextual");
const JsonCrdtLogPinnedPatch_1 = require("./JsonCrdtLogPinnedPatch");
const PlayIcon_1 = require("../icons/PlayIcon");
const DownloadButton_1 = require("./DownloadButton");
const useWindowSize_1 = tslib_1.__importDefault(require("react-use/lib/useWindowSize"));
const css = {
header: (0, nano_theme_1.rule)({
pad: '8px 8px 8px 16px',
}),
content: (0, nano_theme_1.rule)({
pad: '0 8px 8px',
}),
};
const JsonCrdtLog = ({ log, state: _state, view: _view, spacious, filename, renderDisplay, renderLeftToolbar, onModel, }) => {
const { width } = (0, useWindowSize_1.default)();
const [t] = (0, use_t_1.useT)();
const toasts = (0, context_1.useToasts)();
// biome-ignore lint: manual dependency list
const state = React.useMemo(() => (_state ? _state : new JsonCrdtLogState_1.JsonCrdtLogState(log, { view: _view })), [_state, log]);
const view = (0, useBehaviorSubject_1.useBehaviorSubject)(state.view$);
let firstId = log.start().clock;
if (firstId.time === 1) {
const firstPatchId = log.patches.first()?.v.getId();
if (firstPatchId)
firstId = firstPatchId;
}
const pinnedModel = (0, useBehaviorSubject_1.useBehaviorSubject)(state.pinnedModel$);
const model = pinnedModel ?? log.end;
const readonlyEnforcementCounter = (0, useBehaviorSubject_1.useBehaviorSubject)(state.readonlyEnforced$);
// biome-ignore lint: manual dependency list
React.useEffect(() => {
if (onModel) {
onModel(model, !!pinnedModel);
}
}, [model]);
// biome-ignore lint: manual dependency list
React.useEffect(() => {
if (readonlyEnforcementCounter) {
toasts.bottomRight.add({
id: 'readonly',
duration: 2000,
type: 'readonly',
title: 'Model state is pinned',
message: (React.createElement("div", { style: { minWidth: '330px' } },
"Press play button \"",
React.createElement(PlayIcon_1.PlayIcon, { width: 12, height: 12 }),
"\" to resume editing.")),
});
}
}, [readonlyEnforcementCounter]);
const header = (React.createElement(Split_1.Split, { style: { alignItems: 'center' } },
React.createElement(Flex_1.Flex, { style: { alignItems: 'center' } },
React.createElement("div", { style: { marginTop: -1 } },
React.createElement(MiniTitle_1.MiniTitle, null, t('Log'))),
!!renderLeftToolbar && (React.createElement(React.Fragment, null,
React.createElement(Space_1.Space, { horizontal: true, size: 1 }),
renderLeftToolbar())),
React.createElement(Space_1.Space, { horizontal: true, size: 1 }),
!!firstId && width > 500 && (React.createElement(React.Fragment, null,
React.createElement(LogicalTimestamp_1.LogicalTimestamp, { sid: firstId.sid ?? 0, time: firstId.time ?? 0 }),
"\u00A0",
'–',
"\u00A0")),
React.createElement(LogicalTimestamp_1.LogicalTimestamp, { sid: log.end.clock.sid ?? 0, time: log.end.clock.time ? log.end.clock.time - 1 : 0 })),
React.createElement("div", null,
React.createElement(Flex_1.Flex, { style: { alignItems: 'center' } },
React.createElement(DownloadButton_1.DownloadButton, { filename: filename }),
React.createElement(Space_1.Space, { horizontal: true, size: -1 }),
React.createElement(ViewSelect_1.ViewSelect, { state: state }),
React.createElement(Space_1.Space, { horizontal: true, size: 1 }),
React.createElement(PlaybackToolbar_1.PlaybackToolbar, { state: state })))));
let content = null;
switch (view) {
case 'timeline':
content = React.createElement(JsonCrdtLogPinnedPatch_1.JsonCrdtLogPinnedPatch, { filename: filename });
break;
case 'model':
content = (React.createElement(React.Fragment, null,
React.createElement(JsonCrdtLogPinnedPatch_1.JsonCrdtLogPinnedPatch, { filename: filename }),
!!pinnedModel && React.createElement(Space_1.Space, { size: -1 }),
React.createElement(JsonCrdtModel_1.JsonCrdtModel, { state: state.modelState, model: model, filename: filename, readonly: !!pinnedModel, renderDisplay: renderDisplay })));
break;
case 'text':
content = React.createElement(JsonCrdtLogTextual_1.JsonCrdtLogTextual, { log: log });
break;
}
return (React.createElement(context_2.context.Provider, { value: state },
React.createElement(Paper_1.Paper, { contrast: true, round: !!spacious, style: { minWidth: 400, padding: spacious ? '0 8px 8px 8px' : undefined } },
!!pinnedModel && React.createElement(RunningBackground_1.RunningBackground, null),
React.createElement("div", { className: css.header, style: { marginTop: spacious ? (!!pinnedModel ? 6 : 8) : 0 } }, header),
(view === 'timeline' || view === 'model') && React.createElement(Timeline_1.Timeline, { log: log }),
React.createElement("div", { className: css.content }, content))));
};
exports.JsonCrdtLog = JsonCrdtLog;