@shijiu/jsview-vue 2.2.426-test.0 → 2.3.0

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.
Files changed (86) hide show
  1. package/bin/jsview-vue-common.mjs +1 -1
  2. package/bin/jsview-vue.mjs +7506 -6980
  3. package/bin/types/utils/JsViewEngineWidget/JsvFocus/JsvFocusManager.d.ts +11 -2
  4. package/bin/types/utils/JsViewEngineWidget/MetroWidget/DebugFrame.vue.d.ts +8 -0
  5. package/bin/types/utils/JsViewEngineWidget/MetroWidget/DebugTools.d.ts +5 -0
  6. package/bin/types/utils/JsViewEngineWidget/MetroWidget/ListWidget.vue.d.ts +24 -6
  7. package/bin/types/utils/JsViewEngineWidget/MetroWidget/MetroWidget.vue.d.ts +24 -6
  8. package/bin/types/utils/JsViewEngineWidget/MetroWidget/MetroWidgetSetup.d.ts +9 -2
  9. package/bin/types/utils/JsViewEngineWidget/MetroWidget/RenderItem.d.ts +3 -0
  10. package/bin/types/utils/JsViewPlugin/JsvAudio/version.d.mts +1 -0
  11. package/bin/types/utils/JsViewPlugin/JsvAudio/version.d.ts +1 -0
  12. package/bin/types/utils/JsViewPlugin/JsvLatex/BrowserJsvLatex.vue.d.ts +1 -1
  13. package/bin/types/utils/JsViewPlugin/JsvLatex/JsvLatex.vue.d.ts +1 -1
  14. package/bin/types/utils/JsViewPlugin/JsvPlayer/AckEventDefine.d.ts +10 -0
  15. package/bin/types/utils/JsViewPlugin/JsvPlayer/BrowserJsvPlayer.vue.d.ts +1 -2
  16. package/bin/types/utils/JsViewPlugin/JsvPlayer/JsvMedia.d.ts +2 -2
  17. package/bin/types/utils/JsViewVueTools/JsvRuntimeBridge.d.ts +6 -0
  18. package/bin/types/utils/JsViewVueTools/JsvTextureStore/CanvasTexture/Path.d.ts +21 -0
  19. package/bin/types/utils/JsViewVueTools/JsvTextureStore/JsvTextureStore.d.ts +1 -1
  20. package/bin/types/utils/JsViewVueTools/index.d.ts +0 -1
  21. package/bin/types/utils/JsViewVueWidget/Jsv3dDiv.vue.d.ts +120 -0
  22. package/bin/types/utils/JsViewVueWidget/Jsv3dStage.vue.d.ts +144 -0
  23. package/bin/types/utils/JsViewVueWidget/JsvApic/JsvApic/index.d.ts +50 -2
  24. package/bin/types/utils/JsViewVueWidget/JsvApic/JsvApic2/index.d.ts +23 -2
  25. package/bin/types/utils/JsViewVueWidget/JsvDriftScope/JsvDriftScope.vue.d.ts +4 -4
  26. package/bin/types/utils/JsViewVueWidget/JsvFilterView.vue.d.ts +3 -3
  27. package/bin/types/utils/JsViewVueWidget/JsvFlexCell/JsvFullScrAdjust.vue.d.ts +78 -0
  28. package/bin/types/utils/JsViewVueWidget/JsvFlexCell/index.d.ts +1 -0
  29. package/bin/types/utils/JsViewVueWidget/JsvFreeMoveActor/FreeMoveActor.vue.d.ts +3 -3
  30. package/bin/types/utils/JsViewVueWidget/JsvFreeMoveActor/JsvEnvBlocker.vue.d.ts +3 -3
  31. package/bin/types/utils/JsViewVueWidget/JsvFreeMoveActor/SetState.d.ts +1 -0
  32. package/bin/types/utils/JsViewVueWidget/JsvInput/Cursor.vue.d.ts +1 -1
  33. package/bin/types/utils/JsViewVueWidget/JsvMindMap/JsvMindMap.vue.d.ts +3 -3
  34. package/bin/types/utils/JsViewVueWidget/JsvNinePatch.vue.d.ts +4 -4
  35. package/bin/types/utils/JsViewVueWidget/JsvPosterDiv.vue.d.ts +3 -0
  36. package/bin/types/utils/JsViewVueWidget/JsvPosterImage.vue.d.ts +3 -0
  37. package/bin/types/utils/JsViewVueWidget/JsvRipple/JsvRipple.vue.d.ts +3 -3
  38. package/bin/types/utils/JsViewVueWidget/JsvSpray/JsvSpray.vue.d.ts +10 -37
  39. package/bin/types/utils/JsViewVueWidget/JsvSpriteAnim/JsvSpriteAnim.vue.d.ts +1 -1
  40. package/bin/types/utils/JsViewVueWidget/JsvSwiper/JsvSwiper.vue.d.ts +1 -1
  41. package/bin/types/utils/JsViewVueWidget/JsvSwiper3D/JsvSwiper.vue.d.ts +3 -3
  42. package/bin/types/utils/JsViewVueWidget/JsvTextureAnim/JsvTextureAnim.vue.d.ts +3 -2
  43. package/bin/types/utils/JsViewVueWidget/JsvVisibleSensor/JsvVisibleSensor.vue.d.ts +3 -3
  44. package/bin/types/utils/JsViewVueWidget/JsvVisibleSensor/index.d.ts +3 -3
  45. package/bin/types/utils/JsViewVueWidget/index.d.ts +2 -0
  46. package/package.json +1 -1
  47. package/utils/JsViewEngineWidget/CheckType.js +3 -3
  48. package/utils/JsViewEngineWidget/JsvFocus/JsvFocusBlock.vue +25 -6
  49. package/utils/JsViewEngineWidget/JsvFocus/JsvFocusManager.ts +22 -3
  50. package/utils/JsViewEngineWidget/MetroWidget/DebugFrame.vue +22 -0
  51. package/utils/JsViewEngineWidget/MetroWidget/DebugTools.ts +37 -0
  52. package/utils/JsViewEngineWidget/MetroWidget/ListWidget.vue +42 -7
  53. package/utils/JsViewEngineWidget/MetroWidget/MetroWidget.vue +62 -10
  54. package/utils/JsViewEngineWidget/MetroWidget/MetroWidgetSetup.js +205 -91
  55. package/utils/JsViewEngineWidget/MetroWidget/RenderItem.ts +30 -0
  56. package/utils/JsViewPlugin/JsvAudio/version.js +1 -1
  57. package/utils/JsViewPlugin/JsvAudio/version.mjs +1 -1
  58. package/utils/JsViewPlugin/JsvPlayer/AckEventDefine.ts +82 -0
  59. package/utils/JsViewPlugin/JsvPlayer/BrowserJsvPlayer.vue +49 -31
  60. package/utils/JsViewVueTools/JsvRuntimeBridge.js +12 -3
  61. package/utils/JsViewVueTools/JsvTextureStore/CanvasTexture/Path.ts +38 -2
  62. package/utils/JsViewVueTools/JsvTextureStore/JsvTextureStore.ts +1 -1
  63. package/utils/JsViewVueTools/index.js +0 -1
  64. package/utils/JsViewVueWidget/Jsv3dDiv.vue +85 -0
  65. package/utils/JsViewVueWidget/Jsv3dStage.vue +50 -0
  66. package/utils/JsViewVueWidget/JsvApic/JsvApic/index.js +1 -8
  67. package/utils/JsViewVueWidget/JsvApic/JsvApic2/index.js +1 -8
  68. package/utils/JsViewVueWidget/JsvFlexCell/JsvFlexDiv.vue +1 -1
  69. package/utils/JsViewVueWidget/JsvFlexCell/JsvFullScrAdjust.vue +151 -0
  70. package/utils/JsViewVueWidget/JsvFlexCell/JsvScreenFlex.vue +2 -2
  71. package/utils/JsViewVueWidget/JsvFlexCell/index.js +1 -0
  72. package/utils/JsViewVueWidget/JsvFreeMoveActor/SetState.ts +8 -0
  73. package/utils/JsViewVueWidget/JsvInput/EditViewOperator.ts +1 -1
  74. package/utils/JsViewVueWidget/JsvMaskClipDiv.vue +0 -9
  75. package/utils/JsViewVueWidget/JsvNativeSharedDiv.vue +57 -71
  76. package/utils/JsViewVueWidget/JsvPosterDiv.vue +15 -8
  77. package/utils/JsViewVueWidget/JsvPosterImage.vue +11 -1
  78. package/utils/JsViewVueWidget/JsvQrcode/JsvQrcode.vue +1 -1
  79. package/utils/JsViewVueWidget/JsvSpray/JsvSpray.vue +99 -61
  80. package/utils/JsViewVueWidget/JsvTextureAnim/JsvTextureAnim.vue +48 -48
  81. package/utils/JsViewVueWidget/index.js +2 -0
  82. package/bin/browser/BrowserApic.vue.mjs +0 -114
  83. package/bin/browser/BrowserApic2.vue.mjs +0 -108
  84. package/bin/browser/BrowserApicLib.mjs +0 -431
  85. package/bin/types/utils/JsViewVueTools/JsvDemoTester.d.ts +0 -2
  86. package/utils/JsViewVueTools/JsvDemoTester.js +0 -81
@@ -29,10 +29,12 @@ import { WidgetRectInfo } from "./WidgetRectInfo";
29
29
  import ActorControl from "../../JsViewVueWidget/JsvFreeMoveActor/ActorControl.ts";
30
30
  import { TaskType, TaskManager, AnimationManager, SlideTaskType } from "./TaskManager.ts";
31
31
  import { getDirectionByRect, RectCache } from "./Slide.ts";
32
- import { ForgeConst } from "../../JsViewVueTools/ForgeConstDefine.ts";
33
32
  import { FeatureNames, JsvUseFeature } from "../../JsViewVueTools/FeatureActive.ts";
33
+ import { randomColor } from "./DebugTools.ts";
34
34
 
35
35
  const TAG = "MetroWidget";
36
+ const LONGPRESS_TIMEOUT = 600;
37
+ const DATA_ID_KEY = "jsvKey";
36
38
 
37
39
  let metroWidgetTokenGen = 1;
38
40
 
@@ -189,6 +191,7 @@ export const setup = (
189
191
 
190
192
  let innerData = [];
191
193
  let dataList = [];
194
+ let dataKeyList = [];
192
195
  let pageUpdater = null;
193
196
  let enterFocusId = -1;
194
197
  let enterFocusRect = null;
@@ -205,7 +208,7 @@ export const setup = (
205
208
  let childSlideEventLock = false;
206
209
  let onKeyDownLock = false;
207
210
  let visibleInfo = new VisibleInfo();
208
- let alreadyCallItemFocus = false;
211
+ let firstOnItemFocusCalled = false;
209
212
  let innerSlideSetting = props.slideSetting
210
213
  const currentFocusIndex = ref(0);
211
214
 
@@ -215,11 +218,20 @@ export const setup = (
215
218
 
216
219
  const DEFAULT_ANIMATION_DURATION = 200;
217
220
 
218
- const isItemVisible = (item) => {
221
+ //rect {left: number, top: number, width: number, height: number }
222
+ const rectVisibleState = (rect) => {
223
+ if (!rect) {
224
+ return 0;
225
+ }
219
226
  let pos_key = vertical ? "top" : "left";
220
227
  let size_key = vertical ? "height" : "width";
221
- return item.templateInfo[pos_key] >= visibleInfo.start
222
- && item.templateInfo[pos_key] + item.templateInfo[size_key] - 1 < visibleInfo.end;
228
+ if (rect[pos_key] + rect[size_key] - 1 < visibleInfo.start || rect[pos_key] > visibleInfo.end) {
229
+ return 0; // 完全不可见
230
+ } else if (rect[pos_key] < visibleInfo.start || rect[pos_key] + rect[size_key] - 1 > visibleInfo.end) {
231
+ return 1; // 部分可见
232
+ } else {
233
+ return 2; // 完全可见
234
+ }
223
235
  }
224
236
 
225
237
  //tools
@@ -301,12 +313,14 @@ export const setup = (
301
313
  let direction = undefined;
302
314
 
303
315
  let validSlideTask = false;
316
+ let forceSlide = false;
304
317
  if (allTask.slide.length > 0) {
305
318
  validSlideTask = true;
306
319
  //有滚动时, 取消延时加载
307
320
  tryCancelDelayLoad();
308
321
  let slideTask = lastOfArray(allTask.slide);
309
322
  slideDoAnim = slideTask.params.doAnim;
323
+ forceSlide = slideTask.params.force;
310
324
  switch (slideTask.subType) {
311
325
  case SlideTaskType.SLIDE_BY_DIV: {
312
326
  const div = slideTask.params.div;
@@ -364,6 +378,16 @@ export const setup = (
364
378
  let start = focusItem.templateInfo[pos_key] + focusItem.templateInfo[size_key] * anchorInfo.anchor - 1 - anchorInfo.anchorPosition;
365
379
  let totalSize = metroTemplate.getBoundingBoxSize();
366
380
  start = Math.min(Math.max(0, start), totalSize[size_key] - visibleInfo.range)
381
+ //resize的情况下, 需要保证第一个和最后一个尺寸变化后, 能完整展示
382
+ if (focusItem.index == 0) {
383
+ if (start > focusItem.templateInfo[pos_key]) {
384
+ start = 0;
385
+ }
386
+ } else if (focusItem.templateInfo.index == metroTemplate.getTailItemIndex()) {
387
+ if (start + visibleInfo.range > focusItem.templateInfo[pos_key]) {
388
+ start = Math.max(focusItem.templateInfo[size_key] + focusItem.templateInfo[pos_key] - visibleInfo.range, 0);
389
+ }
390
+ }
367
391
  targetVisibleStart = normalizeVisibleStart(start, focusItem.templateInfo, focusItem.templateInfo.index, visibleInfo);
368
392
  } else {
369
393
  targetRect = getItemById(focusId).templateInfo;
@@ -473,7 +497,7 @@ export const setup = (
473
497
  }
474
498
 
475
499
  //处理滚动动画
476
- if (needSlide) {
500
+ if (forceSlide || needSlide) {
477
501
  let animInfo = undefined;
478
502
  if (slideDoAnim) {
479
503
  animInfo = {
@@ -602,12 +626,16 @@ export const setup = (
602
626
  };
603
627
  const _getTemplatePosition = (index) => {
604
628
  let templateInfo = getItemByIndex(index).templateInfo;
605
- return {
606
- left: templateInfo.left,
607
- top: templateInfo.top,
608
- width: templateInfo.width,
609
- height: templateInfo.height,
610
- };
629
+ if (templateInfo) {
630
+ return {
631
+ left: templateInfo.left,
632
+ top: templateInfo.top,
633
+ width: templateInfo.width,
634
+ height: templateInfo.height,
635
+ };
636
+ } else {
637
+ return null;
638
+ }
611
639
  };
612
640
 
613
641
  const id2Index = (id) => {
@@ -668,21 +696,41 @@ export const setup = (
668
696
  }
669
697
  };
670
698
 
699
+ let gazeIndex = -1
671
700
  const onItemFocus = (focusItem, rect) => {
672
701
  //触控模式不触发item的onFocus
673
702
  if (!focusItem) return;
674
703
  setItemZIndex(focusItem, innerData.length, true);
675
704
  if (isFocus) {
676
705
  _itemOnFocusSideEffect(focusItem, rect);
677
- const called = focusItem.onFocus(rect);
678
- if (!called) {
679
- callFocusAfterUpdate = true;
706
+ }
707
+
708
+ if (focusItem.mounted.value) {
709
+ if (gazeIndex != focusItem.templateInfo.index) {
710
+ let preGazeItem = getItemByIndex(gazeIndex);
711
+ if (preGazeItem) {
712
+ preGazeItem.onIgnore();
713
+ }
714
+ gazeIndex = focusItem.templateInfo.index
715
+ focusItem.onGaze(rect);
680
716
  }
681
- return called;
717
+ if (isFocus) {
718
+ focusItem.onFocus(rect);
719
+ }
720
+ return true;
721
+ } else {
722
+ callFocusAfterUpdate = true;
723
+ return false;
682
724
  }
683
- return false;
684
725
  };
685
726
 
727
+ const onItemLongPress = (item) => {
728
+ if (!item) { return; }
729
+ if (isFocus) {
730
+ item.onLongPress();
731
+ }
732
+ }
733
+
686
734
  const setFocusByUid = (uid, needSlide = true, doAnim = false, extraSetting) => {
687
735
  if (!uid || innerData.length <= 0) { return; }
688
736
  //添加item
@@ -814,7 +862,7 @@ export const setup = (
814
862
  }
815
863
  };
816
864
 
817
- const slideToItemInner = (index, doAnim, direction = undefined, preItem = undefined) => {
865
+ const slideToItemInner = (index, doAnim, direction = undefined, preItem = undefined, force = false) => {
818
866
  taskManager.addTask(
819
867
  TaskType.SLIDE,
820
868
  {
@@ -822,6 +870,7 @@ export const setup = (
822
870
  doAnim,
823
871
  direction,
824
872
  preItem,
873
+ force,
825
874
  },
826
875
  SlideTaskType.SLIDE_BY_ITEM);
827
876
  };
@@ -844,22 +893,23 @@ export const setup = (
844
893
  SlideTaskType.SLIDE_BY_DIV);
845
894
  }
846
895
  }
847
- const slideToRect = (rect, doAnim, direction = undefined) => {
848
- if (rect
849
- && typeof rect.left == 'number'
850
- && typeof rect.top == 'number'
851
- && typeof rect.width == 'number'
852
- && typeof rect.height == 'number') {
896
+ const slideToRectInner = (rect, doAnim, direction, force) => {
897
+ if (rect && typeof rect.left == "number" && typeof rect.top == "number" && typeof rect.width == "number" && typeof rect.height == "number") {
853
898
  taskManager.addTask(
854
899
  TaskType.SLIDE,
855
900
  {
856
901
  rect,
857
902
  doAnim,
858
903
  direction,
904
+ force
859
905
  },
860
- SlideTaskType.SLIDE_BY_RECT);
906
+ SlideTaskType.SLIDE_BY_RECT
907
+ );
861
908
  }
862
909
  }
910
+ const slideToRect = (rect, doAnim, direction = undefined) => {
911
+ slideToRectInner(rect, doAnim, direction, false);
912
+ }
863
913
 
864
914
  function ifLayoutChange(type, oldMeasureItem, newMeasureItem) {
865
915
  let changed = newMeasureItem.width !== oldMeasureItem.width
@@ -875,21 +925,26 @@ export const setup = (
875
925
  return changed;
876
926
  }
877
927
 
878
- const DATA_ID_KEY = "jsvKey";
879
- const refreshData = (forceUpdate) => {
928
+ /**
929
+ * 刷新数据
930
+ * @param {boolean} forceUpdate 是否强制更新
931
+ * @param {string} slideToFocus 是否滚动到焦点 "auto" 自动滚动到焦点 "enable" 滚动到焦点 "disable" 不滚动到焦点
932
+ */
933
+ const refreshData = (forceUpdate, slideToFocus = "auto") => {
880
934
  //由于data不支持reactive, 因此数据的更新只通过provideData
881
935
  if (!props.provideData) {
882
936
  console.error("refreshData: provideData is null.");
883
937
  return;
884
938
  }
885
939
  try {
886
- let newData = toRaw(props.provideData());
940
+ let newData = toRaw(safeProvideData()).concat();
887
941
  if (newData instanceof Array) {
888
942
  let maxSameIndex = -1;
889
943
  let layoutChange = false;
890
944
  let onlyDataChangeList = [];
945
+ let targetFocusId = focusId
891
946
  if (focusId >= newData.length) {
892
- _changeFocusId(newData.length - 1, false)
947
+ targetFocusId = newData.length - 1
893
948
  }
894
949
 
895
950
  if (!forceUpdate) {
@@ -897,8 +952,8 @@ export const setup = (
897
952
  let oldItem = dataList[i];
898
953
  let newItem = newData[i];
899
954
  if (newItem) {
900
- if (newItem === oldItem
901
- || (typeof newItem[DATA_ID_KEY] !== "undefined" && typeof oldItem[DATA_ID_KEY] !== "undefined" && newItem[DATA_ID_KEY] === oldItem[DATA_ID_KEY])) {
955
+ if (((typeof newItem[DATA_ID_KEY] == "undefined" || typeof dataKeyList[i] == "undefined") && newItem === oldItem)
956
+ || (typeof newItem[DATA_ID_KEY] !== "undefined" && typeof dataKeyList[i] !== "undefined" && newItem[DATA_ID_KEY] === dataKeyList[i])) {
902
957
  //相同的item
903
958
  maxSameIndex = Math.max(maxSameIndex, i);
904
959
  } else {
@@ -931,7 +986,24 @@ export const setup = (
931
986
  }
932
987
  }
933
988
 
934
- dataList = newData.concat();
989
+ //记录刷新前焦点的可视状态, 若焦点可视, 则刷新后也需要保证焦点的可视
990
+ let needSlide = false;
991
+ if (slideToFocus == "enable") {
992
+ needSlide = true;
993
+ } else if (slideToFocus == "disable") {
994
+ needSlide = false;
995
+ } else {
996
+ let targetRect = mRectCache.getCurRect() ?? mRectCache.getPreRect();
997
+ if (targetRect) {
998
+ needSlide = rectVisibleState(targetRect) !== 0;
999
+ } else {
1000
+ needSlide = rectVisibleState(getItemById(focusId)?.templateInfo) !== 0;
1001
+ }
1002
+ }
1003
+
1004
+ dataList = newData;
1005
+ dataKeyList = dataList.map(i => i[DATA_ID_KEY]);
1006
+
935
1007
  if (forceUpdate || layoutChange) {
936
1008
  //需要更新布局
937
1009
  pageUpdateToken.value++;
@@ -957,16 +1029,16 @@ export const setup = (
957
1029
  if (props.onScroll) {
958
1030
  templateItemAdder.tryAddItemByIndex(dataList.length - 1);
959
1031
  } else {
960
- templateItemAdder.tryAddItemById(focusId);
1032
+ templateItemAdder.tryAddItemById(targetFocusId);
961
1033
  }
962
1034
  } else {
963
- if (maxSameIndex < newData.length) {
1035
+ if (maxSameIndex < newData.length - 1) {
964
1036
  //追加数据
965
1037
  templateItemAdder.updateData(newData);
966
1038
  if (props.onScroll) {
967
1039
  templateItemAdder.tryAddItemByIndex(dataList.length - 1);
968
1040
  } else {
969
- templateItemAdder.tryAddItemById(focusId);
1041
+ templateItemAdder.tryAddItemById(targetFocusId);
970
1042
  }
971
1043
  }
972
1044
 
@@ -984,6 +1056,15 @@ export const setup = (
984
1056
  }
985
1057
  }
986
1058
 
1059
+ if (targetFocusId != focusId) {
1060
+ //重置所有的滚动信息
1061
+ _changeFocusId(targetFocusId, false);
1062
+ visibleInfo = visibleInfo.copy();
1063
+ visibleInfo.start = 0;
1064
+ visibleInfo._startMax = 0;
1065
+ slideDivLeft.value = 0;
1066
+ slideDivTop.value = 0;
1067
+ }
987
1068
  const updater = pageUpdater.update(
988
1069
  metroTemplate,
989
1070
  visibleInfo.startWithPadding - innerKeepTraceRange * pageRange,
@@ -993,13 +1074,17 @@ export const setup = (
993
1074
  permanentItemList
994
1075
  );
995
1076
  updater.apply();
996
- onItemFocus(getItemById(focusId), null);
997
- let targetRect = mRectCache.getCurRect() ?? mRectCache.getPreRect();
998
- if (targetRect) {
999
- slideToRect(targetRect, false);
1000
- } else {
1001
- slideToItem(id2Index(focusId), false);
1077
+ const focusItem = getItemById(focusId);
1078
+ onItemFocus(focusItem, null);
1079
+ if (needSlide) {
1080
+ if (targetRect) {
1081
+ slideToRectInner(targetRect, false, 0, true);
1082
+ } else if (focusItem.itemConfig.itemSlide == METRO_WIDGET_CONST.ITEM_SLIDE.ACT_ITEM_FOCUS) {
1083
+ //只有这个item是控制滚动的才slide, 其他如嵌套时不需要slide
1084
+ slideToItemInner(id2Index(focusId), false, 0, 0, true);
1085
+ }
1002
1086
  }
1087
+
1003
1088
  //template和slideDivStyle均确定后再次重设box condition
1004
1089
  updateTouchBoxCondition();
1005
1090
  }
@@ -1096,6 +1181,7 @@ export const setup = (
1096
1181
  setSlideSetting,
1097
1182
  cancelDelayLoad: tryCancelDelayLoad,
1098
1183
  setSensorSensitivity,
1184
+ getItemLayoutInfo: _getTemplatePosition,
1099
1185
  };
1100
1186
 
1101
1187
  const _calculateNearestItemByRect = (visibleSet, enter_rect_info) => {
@@ -1311,10 +1397,56 @@ export const setup = (
1311
1397
  return false;
1312
1398
  }
1313
1399
 
1400
+ const _moveByKey = (keyCode) => {
1401
+ switch (keyCode) {
1402
+ case 37:
1403
+ _moveToNext(-1, 0);
1404
+ return true;
1405
+ case 38:
1406
+ _moveToNext(0, -1);
1407
+ return true;
1408
+ case 39:
1409
+ _moveToNext(1, 0);
1410
+ return true;
1411
+ case 40:
1412
+ _moveToNext(0, 1);
1413
+ return true;
1414
+ default:
1415
+ return false;
1416
+ }
1417
+ }
1418
+
1419
+ let clickDownReceived = false;
1420
+ let longPressTriggered = false;
1421
+
1422
+ const focusBlockOnKeyUp = (ev) => {
1423
+ if (!props.enableLongPress) {
1424
+ return false;
1425
+ }
1426
+ //支持长按时 onClick 由 keyup 处理
1427
+ //longpress触发时, 不触发onClick
1428
+ //没有keydown, 只有keyup时, 不处理keyup
1429
+ if (!longPressTriggered) {
1430
+ if (ev.keyCode == 13 && clickDownReceived) {
1431
+ clickDownReceived = false;
1432
+ onItemClick(getItemById(focusId));
1433
+ return true;
1434
+ }
1435
+ } else {
1436
+ longPressTriggered = false;
1437
+ }
1438
+ return false;
1439
+ }
1440
+
1441
+ let preStartKeyDownTime = -1;
1314
1442
  const focusBlockOnKeyDown = (ev) => {
1315
1443
  if (onKeyDownLock) {
1316
1444
  return true;
1317
1445
  }
1446
+ if (!ev.repeat) {
1447
+ longPressTriggered = false;
1448
+ preStartKeyDownTime = ev.timeStamp;
1449
+ }
1318
1450
  tryCancelDelayLoad();
1319
1451
  if (mode.getMode() == TOUCH_MODE) {
1320
1452
  if (mode.duringTouch()) {
@@ -1323,34 +1455,24 @@ export const setup = (
1323
1455
  }
1324
1456
  }
1325
1457
 
1326
- switch (ev.keyCode) {
1327
- case 37:
1328
- _moveToNext(-1, 0);
1329
- break;
1330
- case 38:
1331
- _moveToNext(0, -1);
1332
- break;
1333
- case 39:
1334
- _moveToNext(1, 0);
1335
- break;
1336
- case 40:
1337
- _moveToNext(0, 1);
1338
- break;
1339
- case 13:
1458
+ if (_moveByKey(ev.keyCode)) {
1459
+ return true;
1460
+ }
1461
+ if (ev.keyCode == 13) {
1462
+ clickDownReceived = true;
1463
+ if (props.enableLongPress) {
1464
+ if (ev.repeat && ev.timeStamp - preStartKeyDownTime > LONGPRESS_TIMEOUT && !longPressTriggered) {
1465
+ longPressTriggered = true;
1466
+ onItemLongPress(getItemById(focusId));
1467
+ }
1468
+ } else if (!ev.repeat) {
1340
1469
  onItemClick(getItemById(focusId));
1341
- break;
1342
- default:
1343
- //只接受上下左右确定键
1344
- return false;
1470
+ }
1471
+ return true;
1472
+ } else {
1473
+ clickDownReceived = false;
1345
1474
  }
1346
- return true;
1347
- };
1348
-
1349
- const randomColor = () => {
1350
- let randomColor = Math.round(Math.random() * 2 ** 24).toString(16);
1351
- return (
1352
- "#" + new Array(6 - randomColor.length).fill("0").join("") + randomColor + "77"
1353
- );
1475
+ return false;
1354
1476
  };
1355
1477
 
1356
1478
  function updateTouchDivSize() {
@@ -1512,7 +1634,9 @@ export const setup = (
1512
1634
  cur_slide,
1513
1635
  true,
1514
1636
  {
1515
- mergeTmp: true
1637
+ //250207 change: true时, 会导致不可见的item反复加载,释放, 所以改为false
1638
+ //但之前设为true应该是为了保证滚动时的楼层不提前消失, 此后若再遇到这类问题再考虑
1639
+ mergeTmp: false
1516
1640
  });
1517
1641
  return true;
1518
1642
  }
@@ -1682,15 +1806,6 @@ export const setup = (
1682
1806
  if ((innerSlideSetting.BoundaryProtect & SlideSetting.START_PROTECT) > 0) {
1683
1807
  if (vInfo.start >= 0) {
1684
1808
  let boundary = 0;
1685
- const headTemplateInfo = getItemByIndex(0).templateInfo;
1686
- if (
1687
- targetRect
1688
- && (index == headTemplateInfo.index)
1689
- && targetRect[pos_key] + targetRect[size_key] <=
1690
- vInfo.range
1691
- ) {
1692
- boundary = headTemplateInfo[size_key];
1693
- }
1694
1809
  visibleStart = visibleStart < boundary ? 0 : visibleStart;
1695
1810
  } else {
1696
1811
  // 以最后一个item的位置作为动态的保护边界
@@ -1704,13 +1819,6 @@ export const setup = (
1704
1819
  //边界必须大于等于0, 同时若最后一个缩进时, 边界采用最后一个item的位置
1705
1820
  if (vInfo.end <= lastEnd) {
1706
1821
  let boundary = lastVisibleStart;
1707
- if (
1708
- targetRect
1709
- && (index == lastTemplateInfo.index)
1710
- && targetRect[pos_key] - lastVisibleStart >= 0
1711
- ) {
1712
- boundary = lastTemplateInfo[pos_key] - vInfo.range;
1713
- }
1714
1822
  visibleStart = visibleStart > boundary ? lastVisibleStart : visibleStart;
1715
1823
  } else {
1716
1824
  // 以最后一个item的位置作为动态的保护边界
@@ -1926,7 +2034,7 @@ export const setup = (
1926
2034
  _changeFocusId(focus_id, false);
1927
2035
  enterFocusId = -1;
1928
2036
  enterFocusRect = null;
1929
- alreadyCallItemFocus = onItemFocus(getItemById(focusId), preEdgeRect);
2037
+ firstOnItemFocusCalled = onItemFocus(getItemById(focusId), preEdgeRect);;
1930
2038
  props.onFocus?.();
1931
2039
  };
1932
2040
 
@@ -1967,12 +2075,12 @@ export const setup = (
1967
2075
 
1968
2076
  const _getVisibleFocusableItem = () => {
1969
2077
  const focusItem = getItemById(focusId);
1970
- if (isItemVisible(focusItem)) {
2078
+ if (rectVisibleState(focusItem.templateInfo) == 2) {
1971
2079
  return focusItem;
1972
2080
  } else {
1973
2081
  //遍历renderList, 找到第一个可见的 focusable item
1974
2082
  for (let item of renderData.value) {
1975
- if (item.templateInfo.focusable && isItemVisible(item)) {
2083
+ if (item.templateInfo.focusable && rectVisibleState(item.templateInfo) == 2) {
1976
2084
  return item;
1977
2085
  }
1978
2086
  }
@@ -2419,6 +2527,10 @@ export const setup = (
2419
2527
  }
2420
2528
 
2421
2529
  //init
2530
+
2531
+ function safeProvideData() {
2532
+ return props.provideData() ?? [];
2533
+ }
2422
2534
  pageUpdater = new PageUpdater(_updatePage, props.name);
2423
2535
  visibleInfo.range = vertical
2424
2536
  ? widgetRectInfo.contentHeight
@@ -2428,10 +2540,11 @@ export const setup = (
2428
2540
  : { start: widgetRectInfo.padding.left, end: widgetRectInfo.padding.right };
2429
2541
 
2430
2542
  if (props.provideData) {
2431
- dataList = toRaw(props.provideData());
2543
+ dataList = toRaw(safeProvideData())?.concat();
2432
2544
  } else if (props.data) {
2433
- dataList = toRaw(props.data);
2545
+ dataList = toRaw(props.data ?? [])?.concat();
2434
2546
  }
2547
+ dataKeyList = dataList.map(i => i[DATA_ID_KEY]);
2435
2548
 
2436
2549
  templateItemAdder = new TemplateItemAdder(
2437
2550
  metroTemplate,
@@ -2497,8 +2610,8 @@ export const setup = (
2497
2610
  if (initVisibleStart) {
2498
2611
  slideToInner(initVisibleStart, false);
2499
2612
  }
2500
- if (isFocus && !alreadyCallItemFocus) {
2501
- onItemFocus(getItemById(focusId), preEdgeRect);
2613
+ if (!firstOnItemFocusCalled) {
2614
+ firstOnItemFocusCalled = onItemFocus(getItemById(focusId), preEdgeRect);
2502
2615
  }
2503
2616
 
2504
2617
  if (props.enableItemRenderBreak) {
@@ -2527,6 +2640,7 @@ export const setup = (
2527
2640
  focusBlockOnFocus,
2528
2641
  focusBlockOnBlur,
2529
2642
  focusBlockOnKeyDown,
2643
+ focusBlockOnKeyUp,
2530
2644
  focusBlockOnCustomEvent,
2531
2645
  _onFocusableItemEdge,
2532
2646
  exportObject,
@@ -23,8 +23,11 @@ interface CustomerCallbackMap {
23
23
  onFocus?: (rect: object) => void,
24
24
  onBlur?: () => void,
25
25
  onClick?: () => void,
26
+ onLongPress?: () => void,
26
27
  onTap?: () => void,
27
28
  onWidgetEdge?: (rect: object) => void,
29
+ onGaze?: (rect: object) => void,
30
+ onIgnore?: () => void,
28
31
  }
29
32
 
30
33
  export class RenderItem {
@@ -125,6 +128,24 @@ export class RenderItem {
125
128
  }
126
129
  }
127
130
 
131
+ public onGaze(rect: object): boolean {
132
+ if (this.mounted.value) {
133
+ this.customerCallbackMap.onGaze?.(rect);
134
+ return true;
135
+ } else {
136
+ return false;
137
+ }
138
+ }
139
+
140
+ public onIgnore(): boolean {
141
+ if (this.mounted.value) {
142
+ this.customerCallbackMap.onIgnore?.();
143
+ return true;
144
+ } else {
145
+ return false;
146
+ }
147
+ }
148
+
128
149
  public readonly onTap = computed(() => {
129
150
  return this.enableTap ? this.onClick.bind(this) : null;
130
151
  })
@@ -138,6 +159,15 @@ export class RenderItem {
138
159
  }
139
160
  }
140
161
 
162
+ public onLongPress(): boolean {
163
+ if (this.mounted.value) {
164
+ this.customerCallbackMap.onLongPress?.();
165
+ return true;
166
+ } else {
167
+ return false;
168
+ }
169
+ }
170
+
141
171
  public onWidgetEdge(rect: object): boolean {
142
172
  if (this.mounted.value) {
143
173
  this.customerCallbackMap.onWidgetEdge?.(rect);
@@ -16,7 +16,7 @@ let PluginInfo = {
16
16
  listener: "top.JsvAudioPluginLoadResult", //插件加载结果回调
17
17
  listener2: "top.JsvAudioPluginStatus",
18
18
  // debug:true,
19
- // md5:"baafc8ea737adcad5443f44cc0112498"
19
+ md5: "5ab9bfbec33034a6a26df7c1187b3c8f"
20
20
  };
21
21
 
22
22
  // 不要用export default,update-env脚本不能解析
@@ -16,7 +16,7 @@ let PluginInfo = {
16
16
  listener: "top.JsvAudioPluginLoadResult", //插件加载结果回调
17
17
  listener2: "top.JsvAudioPluginStatus",
18
18
  // debug:true,
19
- // md5:"baafc8ea737adcad5443f44cc0112498"
19
+ md5: "5ab9bfbec33034a6a26df7c1187b3c8f" // 插件的md5, 此信息是内网场景回使用,一定要对齐md5
20
20
  };
21
21
 
22
22
  // 不要用export default,update-env脚本不能解析