@twick/timeline 0.14.7 → 0.14.9

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.mjs CHANGED
@@ -991,13 +991,14 @@ class ImageElement extends TrackElement {
991
991
  }
992
992
  }
993
993
  class TextElement extends TrackElement {
994
- constructor(text) {
994
+ constructor(text, props) {
995
995
  super(TIMELINE_ELEMENT_TYPE.TEXT);
996
996
  __publicField(this, "textEffect");
997
997
  this.props = {
998
998
  text,
999
- fill: "#888888"
1000
- //default-grey
999
+ fill: "#888888",
1000
+ //default-grey,
1001
+ ...props || {}
1001
1002
  };
1002
1003
  }
1003
1004
  getTextEffect() {
@@ -1012,6 +1013,9 @@ class TextElement extends TrackElement {
1012
1013
  getLineWidth() {
1013
1014
  return this.props.lineWidth;
1014
1015
  }
1016
+ getProps() {
1017
+ return this.props;
1018
+ }
1015
1019
  setText(text) {
1016
1020
  this.props.text = text;
1017
1021
  return this;
@@ -1056,6 +1060,10 @@ class TextElement extends TrackElement {
1056
1060
  this.props.lineWidth = lineWidth;
1057
1061
  return this;
1058
1062
  }
1063
+ setProps(props) {
1064
+ this.props = structuredClone(props);
1065
+ return this;
1066
+ }
1059
1067
  accept(visitor) {
1060
1068
  return visitor.visitTextElement(this);
1061
1069
  }
@@ -1118,6 +1126,8 @@ class CircleElement extends TrackElement {
1118
1126
  super(TIMELINE_ELEMENT_TYPE.CIRCLE);
1119
1127
  this.props = {
1120
1128
  radius,
1129
+ height: radius * 2,
1130
+ width: radius * 2,
1121
1131
  fill,
1122
1132
  strokeColor: fill,
1123
1133
  lineWidth: 1
@@ -1141,6 +1151,8 @@ class CircleElement extends TrackElement {
1141
1151
  }
1142
1152
  setRadius(radius) {
1143
1153
  this.props.radius = radius;
1154
+ this.props.width = radius * 2;
1155
+ this.props.height = radius * 2;
1144
1156
  return this;
1145
1157
  }
1146
1158
  setStrokeColor(strokeColor) {
@@ -1560,6 +1572,14 @@ class ElementSerializer {
1560
1572
  };
1561
1573
  }
1562
1574
  }
1575
+ const VALIDATION_ERROR_CODE = {
1576
+ ELEMENT_NOT_FOUND: "ELEMENT_NOT_FOUND",
1577
+ ELEMENT_NOT_ADDED: "ELEMENT_NOT_ADDED",
1578
+ ELEMENT_NOT_UPDATED: "ELEMENT_NOT_UPDATED",
1579
+ ELEMENT_NOT_REMOVED: "ELEMENT_NOT_REMOVED",
1580
+ COLLISION_ERROR: "COLLISION_ERROR",
1581
+ INVALID_TIMING: "INVALID_TIMING"
1582
+ };
1563
1583
  class ValidationError extends Error {
1564
1584
  constructor(message, errors, warnings = []) {
1565
1585
  super(message);
@@ -1662,8 +1682,8 @@ class ElementValidator {
1662
1682
  const basicValidation = this.validateBasicProperties(element);
1663
1683
  const errors = [...basicValidation.errors];
1664
1684
  const warnings = [...basicValidation.warnings];
1665
- const props = element.getProps();
1666
- if (!(props == null ? void 0 : props.text)) {
1685
+ const text = element.getText();
1686
+ if (!text || text.trim() === "") {
1667
1687
  errors.push("Caption element must have text content");
1668
1688
  }
1669
1689
  return { errors, warnings };
@@ -1840,11 +1860,13 @@ class Track {
1840
1860
  __publicField(this, "id");
1841
1861
  __publicField(this, "name");
1842
1862
  __publicField(this, "type");
1863
+ __publicField(this, "props");
1843
1864
  __publicField(this, "elements");
1844
1865
  __publicField(this, "validator");
1845
1866
  this.name = name;
1846
1867
  this.id = id ?? `t-${generateShortUuid}`;
1847
1868
  this.type = type;
1869
+ this.props = {};
1848
1870
  this.elements = [];
1849
1871
  this.validator = new ElementValidator();
1850
1872
  }
@@ -1990,6 +2012,13 @@ class Track {
1990
2012
  getElements() {
1991
2013
  return [...this.elements];
1992
2014
  }
2015
+ getProps() {
2016
+ return this.props;
2017
+ }
2018
+ setProps(props) {
2019
+ this.props = structuredClone(props);
2020
+ return this;
2021
+ }
1993
2022
  /**
1994
2023
  * Validates a single element using the track's validator.
1995
2024
  * Checks if the element meets all validation requirements.
@@ -2063,17 +2092,21 @@ class Track {
2063
2092
  try {
2064
2093
  const isValid = this.validateElement(element);
2065
2094
  if (isValid) {
2066
- this.elements.push(element);
2067
- return true;
2095
+ if (this.isElementColliding(element)) {
2096
+ throw new ValidationError("Element is colliding with another element", ["COLLISION_ERROR"]);
2097
+ } else {
2098
+ this.elements.push(element);
2099
+ return true;
2100
+ }
2068
2101
  }
2069
2102
  } catch (error) {
2070
- if (error instanceof ValidationError) {
2071
- throw error;
2072
- }
2073
2103
  throw error;
2074
2104
  }
2075
2105
  return false;
2076
2106
  }
2107
+ isElementColliding(element) {
2108
+ return this.elements.some((e2) => e2.getStart() < element.getEnd() && e2.getEnd() > element.getStart());
2109
+ }
2077
2110
  /**
2078
2111
  * Removes an element from the track.
2079
2112
  * Protected method that should be accessed through TrackFriend.
@@ -2242,6 +2275,7 @@ class Track {
2242
2275
  id: this.id,
2243
2276
  name: this.name,
2244
2277
  type: this.type,
2278
+ props: this.props,
2245
2279
  elements: this.elements.map(
2246
2280
  (element) => element.accept(serializer)
2247
2281
  )
@@ -2279,6 +2313,7 @@ class Track {
2279
2313
  static fromJSON(json) {
2280
2314
  const track = new Track(json.name, json.type ?? "element", json.id);
2281
2315
  track.type = json.type;
2316
+ track.props = json.props;
2282
2317
  track.elements = (json.elements || []).map(ElementDeserializer.fromJSON);
2283
2318
  return track;
2284
2319
  }
@@ -2919,6 +2954,11 @@ class TimelineEditor {
2919
2954
  const track = prevTimelineData == null ? void 0 : prevTimelineData.tracks.find((t2) => t2.getName() === name);
2920
2955
  return track;
2921
2956
  }
2957
+ getSubtiltesTrack() {
2958
+ const prevTimelineData = this.getTimelineData();
2959
+ const track = prevTimelineData == null ? void 0 : prevTimelineData.tracks.find((t2) => t2.getType() === "caption");
2960
+ return track;
2961
+ }
2922
2962
  removeTrackById(id) {
2923
2963
  var _a;
2924
2964
  const tracks = ((_a = this.getTimelineData()) == null ? void 0 : _a.tracks) || [];
@@ -2947,8 +2987,9 @@ class TimelineEditor {
2947
2987
  * @returns Promise<boolean> true if element was added successfully
2948
2988
  */
2949
2989
  async addElementToTrack(track, element) {
2990
+ var _a;
2950
2991
  if (!track) {
2951
- return false;
2992
+ throw new Error("TRACK_NOT_FOUND");
2952
2993
  }
2953
2994
  try {
2954
2995
  const elementAdder = new ElementAdder(track);
@@ -2958,10 +2999,16 @@ class TimelineEditor {
2958
2999
  if (currentData) {
2959
3000
  this.setTimelineData({ tracks: currentData.tracks, updatePlayerData: true });
2960
3001
  }
3002
+ return true;
3003
+ } else {
3004
+ return false;
2961
3005
  }
2962
- return result;
2963
3006
  } catch (error) {
2964
- return false;
3007
+ if (error instanceof ValidationError && ((_a = error.errors) == null ? void 0 : _a.length) > 0) {
3008
+ throw error;
3009
+ } else {
3010
+ throw new Error("ELEMENT_NOT_ADDED");
3011
+ }
2965
3012
  }
2966
3013
  }
2967
3014
  /**
@@ -8013,6 +8060,7 @@ export {
8013
8060
  TimelineProvider,
8014
8061
  Track,
8015
8062
  TrackElement,
8063
+ VALIDATION_ERROR_CODE,
8016
8064
  ValidationError,
8017
8065
  VideoElement,
8018
8066
  WORDS_PER_PHRASE,