UNPKG

molstar

Version:

A comprehensive macromolecular library.

91 lines (90 loc) 5.88 kB
import { jsx as _jsx, jsxs as _jsxs } from "react/jsx-runtime"; /** * Copyright (c) 2025 mol* contributors, licensed under MIT, See LICENSE file for more info. * * @author David Sehnal <david.sehnal@gmail.com> */ import { BehaviorSubject, distinctUntilChanged, map } from 'rxjs'; import { PluginComponent } from '../../../mol-plugin-state/component'; import { getMVSStoriesContext } from '../context'; import Markdown from 'react-markdown'; import { useBehavior } from '../../../mol-plugin-ui/hooks/use-behavior'; import { createRoot } from 'react-dom/client'; import { MarkdownAnchor } from '../../../mol-plugin-ui/controls'; import { PluginReactContext } from '../../../mol-plugin-ui/base'; export class MVSStoriesSnapshotMarkdownModel extends PluginComponent { get viewer() { var _a; return (_a = this.context.state.viewers.value) === null || _a === void 0 ? void 0 : _a.find(v => { var _a; return ((_a = this.options) === null || _a === void 0 ? void 0 : _a.viewerName) === v.name; }); } sync() { var _a, _b, _c; const mng = (_b = (_a = this.viewer) === null || _a === void 0 ? void 0 : _a.model.plugin) === null || _b === void 0 ? void 0 : _b.managers.snapshot; this.state.next({ entry: mng === null || mng === void 0 ? void 0 : mng.current, index: (mng === null || mng === void 0 ? void 0 : mng.current) ? mng === null || mng === void 0 ? void 0 : mng.getIndex(mng.current) : undefined, all: (_c = mng === null || mng === void 0 ? void 0 : mng.state.entries.toArray()) !== null && _c !== void 0 ? _c : [], }); } async mount(root) { this.root = root; createRoot(root).render(_jsx(MVSStoriesSnapshotMarkdownUI, { model: this })); let currentViewer = undefined; let sub = undefined; this.subscribe(this.context.state.viewers.pipe(map(xs => xs.find(v => { var _a; return ((_a = this.options) === null || _a === void 0 ? void 0 : _a.viewerName) === v.name; })), distinctUntilChanged((a, b) => (a === null || a === void 0 ? void 0 : a.model) === (b === null || b === void 0 ? void 0 : b.model))), viewer => { var _a; if (currentViewer !== viewer) { currentViewer = viewer === null || viewer === void 0 ? void 0 : viewer.model; sub === null || sub === void 0 ? void 0 : sub.unsubscribe(); } if (!viewer) return; sub = this.subscribe((_a = viewer.model.plugin) === null || _a === void 0 ? void 0 : _a.managers.snapshot.events.changed, () => { this.sync(); }); this.sync(); }); this.sync(); } constructor(options) { super(); this.options = options; this.root = undefined; this.state = new BehaviorSubject({ all: [] }); this.context = getMVSStoriesContext(options === null || options === void 0 ? void 0 : options.context); } } export function MVSStoriesSnapshotMarkdownUI({ model }) { var _a, _b, _c; const state = useBehavior(model.state); const isLoading = useBehavior(model.context.state.isLoading); const style = { display: 'flex', flexDirection: 'column', height: '100%' }; const className = 'mvs-stories-markdown-explanation'; if (isLoading) { return _jsx("div", { style: style, className: className, children: _jsx("i", { children: "Loading..." }) }); } if (state.all.length === 0) { return _jsx("div", { style: style, className: className, children: _jsx("i", { children: "No snapshot loaded or no description available" }) }); } return _jsxs("div", { style: style, className: className, children: [_jsxs("div", { style: { display: 'flex', flexDirection: 'row', width: '100%', gap: '8px' }, children: [_jsxs("span", { style: { lineHeight: '38px', minWidth: 60, maxWidth: 60, flexShrink: 0 }, children: [typeof state.index === 'number' ? state.index + 1 : '-', "/", state.all.length] }), _jsx("button", { onClick: () => { var _a, _b; return (_b = (_a = model.viewer) === null || _a === void 0 ? void 0 : _a.model.plugin) === null || _b === void 0 ? void 0 : _b.managers.snapshot.applyNext(-1); }, style: { flexGrow: 1, flexShrink: 0 }, children: "Prev" }), _jsx("button", { onClick: () => { var _a, _b; return (_b = (_a = model.viewer) === null || _a === void 0 ? void 0 : _a.model.plugin) === null || _b === void 0 ? void 0 : _b.managers.snapshot.applyNext(1); }, style: { flexGrow: 1, flexShrink: 0 }, children: "Next" })] }), _jsx("div", { style: { flexGrow: 1, overflow: 'hidden', overflowY: 'auto', position: 'relative' }, children: _jsx("div", { style: { position: 'absolute', inset: 0 }, children: _jsx(PluginReactContext.Provider, { value: (_a = model.viewer) === null || _a === void 0 ? void 0 : _a.model.plugin, children: _jsx(Markdown, { skipHtml: true, components: { a: MarkdownAnchor }, children: (_c = (_b = state.entry) === null || _b === void 0 ? void 0 : _b.description) !== null && _c !== void 0 ? _c : 'Description not available' }) }) }) })] }); } export class MVSStoriesSnapshotMarkdownViewer extends HTMLElement { async connectedCallback() { var _a, _b; this.model = new MVSStoriesSnapshotMarkdownModel({ context: { name: (_a = this.getAttribute('context-name')) !== null && _a !== void 0 ? _a : undefined }, viewerName: (_b = this.getAttribute('viewer-name')) !== null && _b !== void 0 ? _b : undefined, }); await this.model.mount(this); } disconnectedCallback() { var _a; (_a = this.model) === null || _a === void 0 ? void 0 : _a.dispose(); this.model = undefined; } constructor() { super(); this.model = undefined; } } window.customElements.define('mvs-stories-snapshot-markdown', MVSStoriesSnapshotMarkdownViewer);