@ledvance/group-ui-biz-bundle 1.0.91 → 1.0.93

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 (33) hide show
  1. package/package.json +1 -1
  2. package/src/modules/biorhythm/BiorhythmBean.ts +1 -1
  3. package/src/modules/diyScene/DefaultScenes.ts +439 -0
  4. package/src/modules/diyScene/DiySceneActions.ts +206 -0
  5. package/src/modules/diyScene/DiySceneEditorPage.tsx +356 -0
  6. package/src/modules/diyScene/DiyScenePage.tsx +281 -0
  7. package/src/modules/diyScene/Router.ts +25 -0
  8. package/src/modules/energyConsumption/EnergyConsumptionActions.ts +134 -119
  9. package/src/modules/energyConsumption/EnergyConsumptionChart.tsx +30 -9
  10. package/src/modules/energyConsumption/component/DateSwitch.tsx +111 -0
  11. package/src/modules/energyConsumption/component/NewBarChart.tsx +16 -3
  12. package/src/modules/fixedTimeForPlug/FixedTimeForPlugPage.tsx +14 -0
  13. package/src/modules/fixedTimeForPlug/ItemCard.tsx +3 -2
  14. package/src/modules/fixedTimingForLight/FixedTimingForLightPage.tsx +14 -0
  15. package/src/modules/fixedTimingForLight/ItemCard.tsx +3 -2
  16. package/src/modules/flags/FlagActions.ts +3 -1
  17. package/src/modules/flags/FlagPage.tsx +4 -3
  18. package/src/modules/mood_new/Interface.ts +1 -0
  19. package/src/modules/mood_new/MoodActions.ts +12 -1
  20. package/src/modules/mood_new/MoodItem.tsx +2 -1
  21. package/src/modules/mood_new/MoodPage.tsx +34 -12
  22. package/src/modules/randomTimeForPlug/ItemCard.tsx +3 -2
  23. package/src/modules/randomTimeForPlug/RandomTimeForPlugPage.tsx +14 -0
  24. package/src/modules/randomTimingForLight/RandomTimingForLightPage.tsx +14 -0
  25. package/src/modules/sleepWakeUp/SleepWakeUpPage.tsx +34 -5
  26. package/src/modules/timeSchedule/Interface.ts +19 -10
  27. package/src/modules/timeSchedule/TimeScheduleActions.ts +7 -1
  28. package/src/modules/timeSchedule/TimeScheduleDetailPage.tsx +116 -26
  29. package/src/modules/timeSchedule/TimeSchedulePage.tsx +1 -0
  30. package/src/modules/timeSchedule/components/ManuaSettings.tsx +35 -3
  31. package/src/modules/timeSchedule/components/ScheduleCard.tsx +5 -6
  32. package/src/modules/timer/TimerAction.ts +1 -1
  33. package/src/navigation/Routers.ts +3 -1
@@ -93,6 +93,7 @@ export interface DefMoodOption extends LightCategory{
93
93
  isSupportColor: boolean;
94
94
  isSupportTemperature: boolean;
95
95
  isSupportBrightness: boolean;
96
+ isRefresh?: boolean
96
97
  }
97
98
 
98
99
  export interface MoodDps {
@@ -205,6 +205,18 @@ export const getRemoteMoodList = async (
205
205
  devId: string,
206
206
  option: DefMoodOption,
207
207
  ) => {
208
+ const defaultScene = getDefMoodList(option);
209
+ if (option.isRefresh){
210
+ const res = await setRemoteMoodList(devId, defaultScene, SceneFeatureId)
211
+ if (res.success){
212
+ return {
213
+ success: true,
214
+ data: defaultScene.map((item, index) =>
215
+ remoteMoodInfo2MoodUIState(item, index, option)
216
+ ),
217
+ }
218
+ }
219
+ }
208
220
  const res = await NativeApi.getJson(devId, SceneFeatureId);
209
221
  const isNormalData = Array.isArray(parseJSON(res?.data));
210
222
  if (res.success && isNormalData) {
@@ -216,7 +228,6 @@ export const getRemoteMoodList = async (
216
228
  };
217
229
  } else {
218
230
  if (res.msg?.includes('资源未找到') || !isNormalData) {
219
- const defaultScene = getDefMoodList(option);
220
231
  const res = await setRemoteMoodList(devId, defaultScene, SceneFeatureId);
221
232
  if (res.success) {
222
233
  return {
@@ -118,8 +118,9 @@ export default withTheme(MoodItem)
118
118
  export function MixMoodColorsLine(props: { mixSubLight: MoodLampInfo; isMix: boolean, type: 'gradient' | 'separate' }) {
119
119
  const { mixSubLight, isMix } = props;
120
120
  const lightColors = !!(mixSubLight.enable && mixSubLight.nodes.length) ? mixSubLight.nodes?.map(n => {
121
+ const s = Math.round(mapFloatToRange(n.s / 100, 30, 100));
121
122
  return n.isColorNode
122
- ? hsv2Hex(n.h, Math.round(n.s), Math.round(mapFloatToRange(n.v / 100, 50, 100)))
123
+ ? hsv2Hex(n.h, s, Math.round(mapFloatToRange(n.v / 100, 50, 100)))
123
124
  : cctToColor(n.colorTemp.toFixed());
124
125
  }) : ['#eee'];
125
126
 
@@ -10,7 +10,7 @@ import {
10
10
  import { useReactive } from 'ahooks';
11
11
  import Strings from '@ledvance/base/src/i18n';
12
12
  import res from '@ledvance/base/src/res';
13
- import { FlatList, StyleSheet, View, Platform } from 'react-native';
13
+ import { FlatList, StyleSheet, View, Platform, Image, TouchableOpacity } from 'react-native';
14
14
  import Tag from '@ledvance/base/src/components/Tag';
15
15
  import Spacer from '@ledvance/base/src/components/Spacer';
16
16
  import InfoText from '@ledvance/base/src/components/InfoText';
@@ -25,6 +25,8 @@ import { cloneDeep, filter, map } from 'lodash';
25
25
  import { useFlagMode } from '../flags/FlagActions';
26
26
  import { WorkMode } from '@ledvance/base/src/utils/interface';
27
27
  import ThemeType from '@ledvance/base/src/config/themeType'
28
+ import { showDialog } from '@ledvance/base/src/utils/common';
29
+ import I18n from '@ledvance/base/src/i18n';
28
30
 
29
31
  const cx = Utils.RatioUtils.convertX;
30
32
  const { withTheme } = Utils.ThemeUtils
@@ -63,17 +65,7 @@ const MoodPage = (props: {theme?: ThemeType}) => {
63
65
 
64
66
  useEffect(() => {
65
67
  state.timerId = setTimeout(() => {
66
- state.loading = true
67
- getRemoteMoodList(
68
- uaGroupInfo.tyGroupId.toString(),
69
- params
70
- ).then(res => {
71
- state.loading = false
72
- if (res.success && Array.isArray(res.data)) {
73
- state.originMoods = cloneDeep(res.data);
74
- console.log(state.originMoods, '< --- originMoods')
75
- }
76
- });
68
+ getMoodList()
77
69
  }, 250);
78
70
 
79
71
  return () => {
@@ -93,6 +85,21 @@ const MoodPage = (props: {theme?: ThemeType}) => {
93
85
  });
94
86
  }, [state.staticTagChecked, state.dynamicTagChecked, state.originMoods]);
95
87
 
88
+ const getMoodList = (isRefresh?: boolean) =>{
89
+ state.loading = true
90
+ getRemoteMoodList(
91
+ uaGroupInfo.tyGroupId.toString(),
92
+ {...params, isRefresh}
93
+ ).then(res => {
94
+ state.loading = false
95
+ if (res.success && Array.isArray(res.data)) {
96
+ state.originMoods = cloneDeep(res.data);
97
+ setMoods(cloneDeep(res.data));
98
+ }
99
+ });
100
+ state.loading = false
101
+ }
102
+
96
103
  const navigationRoute = (isStatic: boolean, mode: 'add' | 'edit', currentMood?: MoodUIInfo) => {
97
104
  const path =
98
105
  mode === 'add'
@@ -307,6 +314,21 @@ const MoodPage = (props: {theme?: ThemeType}) => {
307
314
  }}
308
315
  />
309
316
  </View>}
317
+ <TouchableOpacity style={{ alignItems: 'flex-end',paddingRight: cx(24) }}
318
+ onPress={() => {
319
+ showDialog({
320
+ method: 'confirm',
321
+ title: I18n.getLang('mood_resetbutton'),
322
+ subTitle: I18n.getLang('reset_mooddescription'),
323
+ onConfirm: (_, { close }) => {
324
+ close()
325
+ getMoodList(true)
326
+ }
327
+ })
328
+ }}
329
+ >
330
+ <Image source={res.ic_refresh} style={{ width: cx(24), height: cx(24) }} />
331
+ </TouchableOpacity>
310
332
  <Spacer height={cx(10)} />
311
333
  {state.originMoods.length >= MAX_MOOD_COUNT && (
312
334
  <View style={styles.infoLine}>
@@ -24,10 +24,11 @@ export interface ItemCardProps<T> {
24
24
  is24Hour?: boolean,
25
25
  onSwitch: (enable: boolean) => void
26
26
  onPress: () => void
27
+ onLongPress: () => void
27
28
  }
28
29
 
29
30
  const ItemCard = <T, >(props: ItemCardProps<T>) => {
30
- const {item, is24Hour, onSwitch, onPress} = props
31
+ const {item, is24Hour, onSwitch, onPress, onLongPress} = props
31
32
  // 判断是否关闭
32
33
  const closed = getIsClosed(item)
33
34
 
@@ -56,7 +57,7 @@ const ItemCard = <T, >(props: ItemCardProps<T>) => {
56
57
  },
57
58
  })
58
59
  return (
59
- <Card style={styles.itemCard} onPress={onPress}>
60
+ <Card style={styles.itemCard} onPress={onPress} onLongPress={onLongPress}>
60
61
  <Spacer height={cx(16)}/>
61
62
  <View style={styles.switchLine}>
62
63
  <Text style={styles.time}>
@@ -14,6 +14,7 @@ import ItemCard from "./ItemCard";
14
14
  import {cloneDeep} from "lodash";
15
15
  import InfoText from "@ledvance/base/src/components/InfoText";
16
16
  import ThemeType from '@ledvance/base/src/config/themeType'
17
+ import { showDialog } from "@ledvance/base/src/utils/common";
17
18
 
18
19
  const {convertX: cx, topBarHeight} = Utils.RatioUtils;
19
20
  const { withTheme } = Utils.ThemeUtils
@@ -128,6 +129,19 @@ const RandomTimeForPlugPage = (props: { theme?: ThemeType}) => {
128
129
  onPress={() => {
129
130
  onAddOrEditItem('edit', item)
130
131
  }}
132
+ onLongPress={async () =>{
133
+ showDialog({
134
+ method: 'confirm',
135
+ title: I18n.getLang('cancel_dialog_delete_item_randomtimecycle_titel'),
136
+ subTitle: I18n.getLang('cancel_dialog_delete_item_randomtimecycle_description'),
137
+ onConfirm: async (_, {close}) => {
138
+ close()
139
+ state.loading = true
140
+ await onPost('del', item)
141
+ state.loading = false
142
+ }
143
+ })
144
+ }}
131
145
  />
132
146
  )}
133
147
  keyExtractor={(item: any) => `${item?.index}`}
@@ -14,6 +14,7 @@ import ItemCard from "./ItemCard";
14
14
  import {cloneDeep} from "lodash";
15
15
  import InfoText from "@ledvance/base/src/components/InfoText";
16
16
  import ThemeType from '@ledvance/base/src/config/themeType'
17
+ import { showDialog } from "@ledvance/base/src/utils/common";
17
18
 
18
19
  const {convertX: cx, topBarHeight} = Utils.RatioUtils;
19
20
  const { withTheme } = Utils.ThemeUtils
@@ -131,6 +132,19 @@ const RandomTimeForLightPage = (props: { theme?: ThemeType}) => {
131
132
  onPress={() => {
132
133
  onAddOrEditItem('edit', item)
133
134
  }}
135
+ onLongPress={async () =>{
136
+ showDialog({
137
+ method: 'confirm',
138
+ title: I18n.getLang('cancel_dialog_delete_item_randomtimecycle_titel'),
139
+ subTitle: I18n.getLang('cancel_dialog_delete_item_randomtimecycle_description'),
140
+ onConfirm: async (_, {close}) => {
141
+ close()
142
+ state.loading = true
143
+ await onPost('del', item)
144
+ state.loading = false
145
+ }
146
+ })
147
+ }}
134
148
  />
135
149
  )}
136
150
  keyExtractor={(item: any) => `${item?.index}`}
@@ -10,7 +10,7 @@ import {useDeviceInfo, useSystemTimeFormate} from "@ledvance/base/src/models/mod
10
10
  import {useReactive, useUpdateEffect} from "ahooks";
11
11
  import CustomListDialog from "@ledvance/base/src/components/CustomListDialog";
12
12
  import {SwitchButton, Utils} from "tuya-panel-kit";
13
- import {convertMinutesTo12HourFormat, getIsClosed, loopText} from "@ledvance/base/src/utils/common";
13
+ import {convertMinutesTo12HourFormat, getIsClosed, loopText, showDialog} from "@ledvance/base/src/utils/common";
14
14
  import TextButton from "@ledvance/base/src/components/TextButton";
15
15
  import {ui_biz_routerKey} from "../../navigation/Routers";
16
16
  import {cloneDeep} from "lodash";
@@ -49,6 +49,7 @@ const SleepWakeUpPage = (props: {theme?: ThemeType}) => {
49
49
  sleepScheduleList: cloneDeep(sleepList),
50
50
  wakeUpScheduleList: cloneDeep(wakeUpList),
51
51
  filteredScheduleList: [] as any[],
52
+ loading: false
52
53
  })
53
54
 
54
55
  const isMaxNum = useMemo(() => {
@@ -192,7 +193,7 @@ const SleepWakeUpPage = (props: {theme?: ThemeType}) => {
192
193
  alignItems: 'center'
193
194
  },
194
195
  emptyBtn: {
195
- backgroundColor: props.theme?.button.primary,
196
+ backgroundColor: props.theme?.button.active,
196
197
  borderRadius: cx(5),
197
198
  paddingHorizontal: cx(15),
198
199
  paddingVertical: cx(10)
@@ -255,6 +256,7 @@ const SleepWakeUpPage = (props: {theme?: ThemeType}) => {
255
256
  onHeadlineIconClick={() => {
256
257
  state.showAddSchedulePopover = !state.showAddSchedulePopover
257
258
  }}
259
+ loading={state.loading}
258
260
  >
259
261
  <View style={{ marginHorizontal: cx(24) }}>
260
262
  <Text style={{ color: props.theme?.global.fontColor, fontSize: cx(12) }}>
@@ -302,6 +304,32 @@ const SleepWakeUpPage = (props: {theme?: ThemeType}) => {
302
304
  settingTime: new Date().getTime()
303
305
  })
304
306
  }}
307
+ onLongPress={() =>{
308
+ showDialog({
309
+ method: 'confirm',
310
+ title: I18n.getLang(
311
+ item.isSleep
312
+ ? 'cancel_dialog_delete_item_sleepschedule_titel'
313
+ : 'cancel_dialog_delete_item_wakeupschedule_titel'
314
+ ),
315
+ subTitle: I18n.getLang(
316
+ item.isSleep
317
+ ? 'cancel_dialog_delete_item_sleepschedule_description'
318
+ : 'cancel_dialog_delete_item_wakeupschedule_description'
319
+ ),
320
+ onConfirm: async (_, { close }) => {
321
+ close();
322
+ if (state.loading) return;
323
+ state.loading = true;
324
+ await modDeleteTimeSchedule(
325
+ 'del',
326
+ item.isSleep,
327
+ item
328
+ );
329
+ state.loading = false;
330
+ },
331
+ });
332
+ }}
305
333
  />
306
334
  )}
307
335
  ListHeaderComponent={() => (<Spacer height={cx(10)} />)}
@@ -374,16 +402,17 @@ const SleepWakeUpPage = (props: {theme?: ThemeType}) => {
374
402
  )
375
403
  }
376
404
 
377
- const SleepWakeUpCard = ({ sleepWakeUp, is24HourClock, onSwitch, onPress, styles }: {
405
+ const SleepWakeUpCard = ({ sleepWakeUp, is24HourClock, onSwitch, onPress, onLongPress, styles }: {
378
406
  sleepWakeUp: SleepWakeUpItem,
379
407
  onSwitch: (enable: boolean) => void,
380
408
  onPress: () => void
409
+ onLongPress: () => void
381
410
  is24HourClock: boolean
382
411
  styles: StyleSheet.NamedStyles<any>
383
412
  }) => {
384
413
  const closed = getIsClosed({weeks: sleepWakeUp.weeks, settingTime: sleepWakeUp.settingTime, endTime: getEndTime(sleepWakeUp)})
385
414
  return (
386
- <Card style={styles.randomTimingCard} onPress={onPress}>
415
+ <Card style={styles.randomTimingCard} onPress={onPress} onLongPress={onLongPress}>
387
416
  <Spacer height={cx(16)} />
388
417
  <View style={styles.switchLine}>
389
418
  <Text style={styles.time}>
@@ -393,7 +422,7 @@ const SleepWakeUpCard = ({ sleepWakeUp, is24HourClock, onSwitch, onPress, styles
393
422
  thumbStyle={{ elevation: 0 }}
394
423
  onValueChange={onSwitch} />
395
424
  </View>
396
- <Text style={styles.loopText}>{loopText(sleepWakeUp.weeks, parseTimer(getStartTime(sleepWakeUp) * 60))}</Text>
425
+ <Text style={styles.loopText}>{loopText(sleepWakeUp.weeks, parseTimer(getEndTime(sleepWakeUp) * 60))}</Text>
397
426
  <Spacer height={cx(5)} />
398
427
  <Text style={styles.loopText}>{sleepWakeUp.name}</Text>
399
428
  <Spacer height={cx(10)} />
@@ -1,3 +1,7 @@
1
+ import I18n from "@ledvance/base/src/i18n";
2
+ import { AdjustType, DiySceneInfo } from "@ledvance/base/src/utils/interface";
3
+ import { MoodInfo, MoodUIInfo } from "../mood_new/Interface";
4
+
1
5
  export interface IAddSingleTime {
2
6
  bizId: string;
3
7
  bizType?: string;
@@ -15,8 +19,6 @@ export interface IQueryTimerTasks {
15
19
  category?: string;
16
20
  }
17
21
 
18
-
19
-
20
22
  export interface IModifySingleTimer {
21
23
  bizId: string;
22
24
  bizType?: string;
@@ -40,10 +42,6 @@ export enum UVCFanMode {
40
42
  Normal = 'normal'
41
43
  }
42
44
 
43
-
44
- import I18n from "@ledvance/base/src/i18n";
45
- import { MoodInfo, MoodUIInfo } from "../mood_new/Interface";
46
-
47
45
  export interface Timer {
48
46
  status: number;
49
47
  loops: string;
@@ -84,6 +82,7 @@ interface judgmentSupport {
84
82
  isMixLight?: boolean;
85
83
  isFanLight?: boolean;
86
84
  isUVCFan?: boolean;
85
+ isMoodStrip?: boolean;
87
86
  }
88
87
 
89
88
  export interface ManualSettingProps extends judgmentSupport {
@@ -100,7 +99,8 @@ export enum DeviceType {
100
99
  MixLight = 'mixLight',
101
100
  StripLight = 'stripLight',
102
101
  CeilingLight = 'ceilingLight',
103
- FanLight = 'fanLight'
102
+ FanLight = 'fanLight',
103
+ MoodStrip = 'moodStrip',
104
104
  }
105
105
  // export type DeviceType = 'LightSource' | 'CeilingLight' | 'StringLight' | 'StripLight' | 'MixLight';
106
106
 
@@ -135,12 +135,17 @@ export interface FanLightData extends DeviceData {
135
135
  disinfect: boolean
136
136
  }
137
137
 
138
+ export interface MoodStripData extends DeviceData {
139
+ adjustType: AdjustType
140
+ }
141
+
138
142
  export type ComponentConfig =
139
143
  | { type: DeviceType.LightSource; deviceData: DeviceData }
140
144
  | { type: DeviceType.MixLight; deviceData: MixLightData }
141
145
  | { type: DeviceType.StripLight; deviceData: StripLightData }
142
146
  | { type: DeviceType.CeilingLight; deviceData: CeilingLightData }
143
147
  | { type: DeviceType.FanLight; deviceData: FanLightData }
148
+ | { type: DeviceType.MoodStrip; deviceData: MoodStripData}
144
149
 
145
150
  export interface TimeScheduleDetailState {
146
151
  timeSchedule: Timer;
@@ -152,15 +157,19 @@ export interface TimeScheduleDetailState {
152
157
  loading: boolean;
153
158
  moodLoading: boolean;
154
159
  manualData: ComponentConfig;
155
- mood?: MoodInfo;
156
- moods: MoodUIInfo[];
160
+ mood?: MoodInfo | DiySceneInfo;
161
+ moods: MoodUIInfo[] | DiySceneInfo[];
162
+ filterMoods: MoodUIInfo[] | DiySceneInfo[];
163
+ staticTagChecked: boolean;
164
+ dynamicTagChecked: boolean;
165
+ diyTagChecked: boolean;
157
166
  timerId: any;
158
167
  moodName: string;
159
168
  }
160
169
 
161
170
  export interface DeviceStateType {
162
171
  deviceData: ComponentConfig
163
- mood?: MoodInfo
172
+ mood?: MoodInfo | DiySceneInfo
164
173
  isManual: boolean
165
174
  }
166
175
 
@@ -1,9 +1,10 @@
1
1
  import { commonApi } from "@tuya/tuya-panel-api"
2
- import { IAddSingleTime, IQueryTimerTasks, IModifySingleTimer, IModDeleteTaskByIds, UVCFanMode } from "@ledvance/group-ui-biz-bundle/src/modules/timeSchedule/Interface"
2
+ import { IAddSingleTime, IQueryTimerTasks, IModifySingleTimer, IModDeleteTaskByIds, UVCFanMode } from "./Interface"
3
3
  import { flatMapDeep } from "lodash";
4
4
  import I18n from "@ledvance/base/src/i18n";
5
5
  import { ColorList } from '@ledvance/base/src/components/StripAdjustView';
6
6
  import { parseJSON } from "@tuya/tuya-panel-lamp-sdk/lib/utils";
7
+ import { AdjustType } from "@ledvance/base/src/utils/interface";
7
8
 
8
9
  export const defDeviceData = {
9
10
  h: 0,
@@ -40,6 +41,11 @@ export const defFanLightDeviceData = {
40
41
  disinfect: false
41
42
  }
42
43
 
44
+ export const defMoodStripDeviceData = {
45
+ ...defDeviceData,
46
+ adjustType: AdjustType.COLOUR
47
+ }
48
+
43
49
  export const addTimeSchedule = async (props: IAddSingleTime) => {
44
50
  try {
45
51
  const res = await commonApi.timerApi.addSingleTimer({
@@ -37,13 +37,16 @@ import DeleteButton from '@ledvance/base/src/components/DeleteButton';
37
37
  import SegmentControl from '@ledvance/base/src/components/segmentControl';
38
38
  import { useParams } from '@ledvance/base/src/hooks/Hooks';
39
39
  import ManualSettings from './components/ManuaSettings';
40
- import { defDeviceData, defMixDeviceData, defStripDeviceData, defFanLightDeviceData } from './TimeScheduleActions';
40
+ import { defDeviceData, defMixDeviceData, defStripDeviceData, defFanLightDeviceData, defMoodStripDeviceData } from './TimeScheduleActions';
41
41
  import MoodItem from '../mood_new/MoodItem';
42
42
  import Summary from './components/Summary'
43
43
  import { getRemoteMoodList } from '../mood_new/MoodActions'
44
- import { MoodUIInfo } from '../mood_new/Interface';
44
+ import {MoodInfo, MoodUIInfo } from '../mood_new/Interface';
45
45
  import InfoText from '@ledvance/base/src/components/InfoText';
46
46
  import ThemeType from '@ledvance/base/src/config/themeType'
47
+ import Tag from '@ledvance/base/src/components/Tag';
48
+ import { DiySceneInfo } from '@ledvance/base/src/utils/interface';
49
+ import DiySceneItem from '@ledvance/base/src/components/DiySceneItem';
47
50
 
48
51
  const { convertX: cx } = Utils.RatioUtils;
49
52
  const { withTheme } = Utils.ThemeUtils
@@ -61,6 +64,7 @@ const TimeScheduleDetailPage = (props: { theme?: ThemeType }) => {
61
64
  const uaGroupInfo = useUAGroupInfo()
62
65
  const is24HourClock = useSystemTimeFormate();
63
66
  const [moods, setMoods] = useMoods();
67
+ type MoodsType = typeof params.isMoodStrip extends true ? DiySceneInfo[] : MoodUIInfo[]
64
68
  const state = useReactive<TimeScheduleDetailState>({
65
69
  timeSchedule: params.mode === 'add' ? newTimeSchedule() : cloneDeep(params.timeSchedule),
66
70
  dps: params.mode === 'add' ? {} : params.timeSchedule.dps,
@@ -76,6 +80,10 @@ const TimeScheduleDetailPage = (props: { theme?: ThemeType }) => {
76
80
  : params.manualDataDp2Obj(params.timeSchedule.dps)?.deviceData,
77
81
  mood: params.mode === 'add' ? undefined : params.manualDataDp2Obj(params.timeSchedule.dps)?.mood,
78
82
  moods: cloneDeep(moods),
83
+ filterMoods: cloneDeep(moods),
84
+ staticTagChecked: true,
85
+ dynamicTagChecked: true,
86
+ diyTagChecked: true,
79
87
  timerId: undefined,
80
88
  moodName: '',
81
89
  });
@@ -145,15 +153,37 @@ const TimeScheduleDetailPage = (props: { theme?: ThemeType }) => {
145
153
  useEffect(() => {
146
154
  if (state.moods?.length) {
147
155
  state.moodName =
148
- state.moods.find(m =>
156
+ (state.moods as MoodsType).find(m =>
149
157
  params.isCeilingLight
150
- ? m.mainLamp.id === state.mood?.mainLamp.id &&
151
- m.secondaryLamp.id === state.mood?.secondaryLamp.id
158
+ ? m.mainLamp.id === (state.mood as MoodInfo)?.mainLamp.id &&
159
+ m.secondaryLamp.id === (state.mood as MoodInfo)?.secondaryLamp.id
152
160
  : m.id === state.mood?.id
153
161
  )?.name || '';
154
162
  }
155
163
  }, [state.mood, state.moods]);
156
164
 
165
+ useEffect(() => {
166
+ if (params.isMoodStrip) {
167
+ state.filterMoods = (state.moods as DiySceneInfo[]).filter(item => {
168
+ return [state.staticTagChecked, state.dynamicTagChecked, state.diyTagChecked].every(it => !it)
169
+ || (state.staticTagChecked && item.type === 'Static')
170
+ || (state.dynamicTagChecked && item.type === 'Dynamic')
171
+ || (state.diyTagChecked && item.type === 'DIY')
172
+ })
173
+ } else {
174
+ state.filterMoods = (state.moods as MoodsType).filter(item => {
175
+ return (
176
+ (state.staticTagChecked && state.dynamicTagChecked) ||
177
+ (!state.staticTagChecked && !state.dynamicTagChecked) ||
178
+ (state.staticTagChecked && item.mainLamp.nodes.length < 2) ||
179
+ (state.dynamicTagChecked &&
180
+ (item.secondaryLamp.nodes.length > 1 || item.mainLamp.nodes.length > 1))
181
+ );
182
+ });
183
+ }
184
+
185
+ }, [state.staticTagChecked, state.dynamicTagChecked, state.diyTagChecked, state.moods]);
186
+
157
187
  const getFormateTime = useCallback((time: number | string) => {
158
188
  if (typeof time === 'number') {
159
189
  return `${toFixedString(Math.trunc(time / 60), 2)}:${toFixedString(time % 60, 2)}`;
@@ -211,7 +241,7 @@ const TimeScheduleDetailPage = (props: { theme?: ThemeType }) => {
211
241
  }, [params.applyForList.length, params.applyForDisabled]);
212
242
 
213
243
  const getMoodItemEnable = useCallback((item: MoodUIInfo ) =>{
214
- return params.isCeilingLight ? ((item.mainLamp.id === state.mood?.mainLamp?.id) && (item.secondaryLamp.id === state.mood?.secondaryLamp?.id)) : item.id === state.mood?.id
244
+ return params.isCeilingLight ? ((item.mainLamp.id === (state.mood as MoodInfo)?.mainLamp?.id) && (item.secondaryLamp.id === (state.mood as MoodInfo)?.secondaryLamp?.id)) : item.id === state.mood?.id
215
245
  }, [state.mood, params.isCeilingLight])
216
246
 
217
247
  const styles = StyleSheet.create({
@@ -264,6 +294,10 @@ const TimeScheduleDetailPage = (props: { theme?: ThemeType }) => {
264
294
  color: props.theme?.global.fontColor,
265
295
  fontSize: cx(14)
266
296
  },
297
+ tagLine: {
298
+ flexDirection: 'row',
299
+ marginHorizontal: cx(24),
300
+ }
267
301
  })
268
302
 
269
303
  return (
@@ -429,7 +463,7 @@ const TimeScheduleDetailPage = (props: { theme?: ThemeType }) => {
429
463
  {showMoodFanSelectText && <InfoText
430
464
  style={{marginHorizontal: cx(24)}}
431
465
  icon={res.ic_warning_amber}
432
- contentColor={props.theme?.global.warnging}
466
+ contentColor={props.theme?.global.warning}
433
467
  text={I18n.getLang('timeschedule_add_schedule_devicestate_sec_warning_text')}
434
468
  />}
435
469
  {state.isManual ? (
@@ -454,25 +488,77 @@ const TimeScheduleDetailPage = (props: { theme?: ThemeType }) => {
454
488
  }}
455
489
  />
456
490
  ) : (
457
- !showMoodFanSelectText ? <FlatList
458
- data={state.moods}
459
- renderItem={({ item }) => {
460
- return (
461
- <MoodItem
462
- enable={getMoodItemEnable(item)}
463
- mood={item}
464
- isMix={!!(params.isMixLight || params.isCeilingLight)}
465
- onSwitch={_ => {
466
- state.mood = cloneDeep(item);
491
+ !showMoodFanSelectText ? (
492
+ <View>
493
+ {!(params.isStringLight || params.isStripLight) && <View style={styles.tagLine}>
494
+ <Tag
495
+ checked={state.staticTagChecked}
496
+ text={I18n.getLang('mood_overview_filter_name_text1')}
497
+ onCheckedChange={checked => {
498
+ state.staticTagChecked = checked;
499
+ }}
500
+ />
501
+ <Spacer width={cx(8)} height={0} />
502
+ <Tag
503
+ checked={state.dynamicTagChecked}
504
+ text={I18n.getLang('mood_overview_filter_name_text2')}
505
+ onCheckedChange={checked => {
506
+ state.dynamicTagChecked = checked;
507
+ }}
508
+ />
509
+ {
510
+ params.isMoodStrip && <>
511
+ <Spacer width={cx(8)} height={0}/>
512
+ <Tag
513
+ checked={state.diyTagChecked}
514
+ text={I18n.getLang('mood_overview_field_chip_diy')}
515
+ onCheckedChange={checked => {
516
+ state.diyTagChecked = checked;
517
+ }}
518
+ />
519
+ </>
520
+ }
521
+ </View>}
522
+ {params.isMoodStrip ? <FlatList
523
+ data={state.filterMoods as DiySceneInfo[]}
524
+ renderItem={({item}) => {
525
+ return (
526
+ <DiySceneItem
527
+ enable={item.id === state.mood?.id}
528
+ scene={item}
529
+ onSwitch={_ => {
530
+ state.mood = cloneDeep(item);
531
+ }}
532
+ />
533
+ );
467
534
  }}
535
+ ListHeaderComponent={() => <Spacer height={cx(10)}/>}
536
+ ItemSeparatorComponent={() => <Spacer/>}
537
+ ListFooterComponent={() => <Spacer/>}
538
+ keyExtractor={item => `${item.name}`}
539
+ /> :
540
+ <FlatList
541
+ data={state.filterMoods as MoodUIInfo[]}
542
+ renderItem={({ item }) => {
543
+ return (
544
+ <MoodItem
545
+ enable={getMoodItemEnable(item)}
546
+ mood={item}
547
+ isMix={!!(params.isMixLight || params.isCeilingLight)}
548
+ onSwitch={_ => {
549
+ state.mood = cloneDeep(item);
550
+ }}
551
+ />
552
+ );
553
+ }}
554
+ ListHeaderComponent={() => <Spacer height={cx(10)} />}
555
+ ItemSeparatorComponent={() => <Spacer />}
556
+ ListFooterComponent={() => <Spacer />}
557
+ keyExtractor={item => `${item.name}`}
468
558
  />
469
- );
470
- }}
471
- ListHeaderComponent={() => <Spacer height={cx(10)} />}
472
- ItemSeparatorComponent={() => <Spacer />}
473
- ListFooterComponent={() => <Spacer />}
474
- keyExtractor={item => `${item.name}`}
475
- /> : <View></View>
559
+ }
560
+ </View>
561
+ ) : <View></View>
476
562
  )}
477
563
  <Spacer />
478
564
 
@@ -614,7 +700,9 @@ const getDefaultManual = (props: TimeScheduleDetailPageParams): ComponentConfig
614
700
  DeviceType.FanLight
615
701
  : props.isCeilingLight
616
702
  ? DeviceType.CeilingLight
617
- : DeviceType.LightSource;
703
+ : props.isMoodStrip
704
+ ? DeviceType.MoodStrip
705
+ : DeviceType.LightSource
618
706
  const deviceData =
619
707
  (deviceType === DeviceType.StripLight || deviceType === DeviceType.CeilingLight)
620
708
  ? defStripDeviceData
@@ -622,7 +710,9 @@ const getDefaultManual = (props: TimeScheduleDetailPageParams): ComponentConfig
622
710
  ? defMixDeviceData
623
711
  : deviceType === DeviceType.FanLight
624
712
  ? defFanLightDeviceData
625
- : defDeviceData;
713
+ : deviceType === DeviceType.MoodStrip
714
+ ? defMoodStripDeviceData
715
+ : defDeviceData;
626
716
  // @ts-ignore
627
717
  return {
628
718
  type: deviceType,
@@ -38,6 +38,7 @@ export interface TimeSchedulePageParams {
38
38
  isMixLight?: boolean;
39
39
  isFanLight?: boolean
40
40
  isUVCFan?: boolean;
41
+ isMoodStrip?: boolean
41
42
  applyForList: ApplyForItem[];
42
43
  applyForDisabled?: boolean; // 是否可以选择apply for
43
44
  manualDataDp2Obj: (dps: Record<string, any>) => DeviceStateType;