block.ts 2.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110
  1. import { BlockData, BlockType, DocumentState, NestedBlock } from '$app/interfaces/document';
  2. import { BlockPB } from '@/services/backend';
  3. import { Log } from '$app/utils/log';
  4. import { nanoid } from 'nanoid';
  5. export function blockPB2Node(block: BlockPB) {
  6. let data = {};
  7. try {
  8. data = JSON.parse(block.data);
  9. } catch {
  10. Log.error('[Document Open] json parse error', block.data);
  11. }
  12. const node = {
  13. id: block.id,
  14. type: block.ty as BlockType,
  15. parent: block.parent_id,
  16. children: block.children_id,
  17. data,
  18. externalId: block.external_id,
  19. externalType: block.external_type,
  20. };
  21. return node;
  22. }
  23. export function generateId() {
  24. return nanoid(10);
  25. }
  26. export function getPrevLineId(state: DocumentState, id: string) {
  27. const node = state.nodes[id];
  28. if (!node.parent) return;
  29. const parent = state.nodes[node.parent];
  30. const children = state.children[parent.children];
  31. const index = children.indexOf(id);
  32. const prevNodeId = children[index - 1];
  33. const prevNode = state.nodes[prevNodeId];
  34. if (!prevNode) {
  35. return parent.id;
  36. }
  37. // find prev line
  38. let prevLineId = prevNode.id;
  39. while (prevLineId) {
  40. const prevLineChildren = state.children[state.nodes[prevLineId].children];
  41. if (prevLineChildren.length === 0) break;
  42. prevLineId = prevLineChildren[prevLineChildren.length - 1];
  43. }
  44. return prevLineId || parent.id;
  45. }
  46. export function getNextLineId(state: DocumentState, id: string) {
  47. const node = state.nodes[id];
  48. const firstChild = state.children[node.children][0];
  49. if (firstChild) return firstChild;
  50. let nextNodeId = getNextNodeId(state, id);
  51. if (!node.parent) return;
  52. let parent: NestedBlock | null = state.nodes[node.parent];
  53. while (!nextNodeId && parent) {
  54. nextNodeId = getNextNodeId(state, parent.id);
  55. parent = parent.parent ? state.nodes[parent.parent] : null;
  56. }
  57. return nextNodeId;
  58. }
  59. export function getNextNodeId(state: DocumentState, id: string) {
  60. const node = state.nodes[id];
  61. if (!node.parent) return;
  62. const parent = state.nodes[node.parent];
  63. const children = state.children[parent.children];
  64. const index = children.indexOf(id);
  65. const nextNodeId = children[index + 1];
  66. return nextNodeId;
  67. }
  68. export function getPrevNodeId(state: DocumentState, id: string) {
  69. const node = state.nodes[id];
  70. if (!node.parent) return;
  71. const parent = state.nodes[node.parent];
  72. const children = state.children[parent.children];
  73. const index = children.indexOf(id);
  74. const prevNodeId = children[index - 1];
  75. return prevNodeId;
  76. }
  77. export function newBlock<Type>(type: BlockType, parentId: string, data?: BlockData<Type>): NestedBlock<Type> {
  78. return {
  79. id: generateId(),
  80. type,
  81. parent: parentId,
  82. children: generateId(),
  83. data: data ? data : {},
  84. };
  85. }