@ledvance/group-ui-biz-bundle 1.0.128 → 1.0.130

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/package.json CHANGED
@@ -4,7 +4,7 @@
4
4
  "name": "@ledvance/group-ui-biz-bundle",
5
5
  "pid": [],
6
6
  "uiid": "",
7
- "version": "1.0.128",
7
+ "version": "1.0.130",
8
8
  "scripts": {},
9
9
  "dependencies": {
10
10
  "@ledvance/base": "^1.x",
@@ -84,7 +84,8 @@ export const useFlag: UseFlagType = (params) => {
84
84
  }else{
85
85
  const paintHex = drawToolFormat({
86
86
  adjustCode: 3,
87
- colors: flag.colors.map(f => ColorUtils.hsv2hex(f.h,f.s,f.v)).slice(0, 5),
87
+ colors: flag.colors.map(f => ColorUtils.hsv2hex(f.h,f.s,f.v)),
88
+ num: flag.colors.length,
88
89
  daubType: 0,
89
90
  effect: 0
90
91
  })
@@ -1,5 +1,5 @@
1
1
  import {NavigationRoute} from "tuya-panel-kit";
2
- import SwitchInching from "./SwithInching";
2
+ import SwitchInching from "./SwitchInching";
3
3
  import {ui_biz_routerKey} from "../../navigation/Routers";
4
4
 
5
5
  const SwitchInchingRouters: NavigationRoute[] = [
@@ -0,0 +1,203 @@
1
+ import React, {useEffect, useMemo, useRef, useState} from "react";
2
+ import {ScrollView, StyleSheet, Text, View} from "react-native";
3
+ import Page from "@ledvance/base/src/components/Page";
4
+ import {useUAGroupInfo} from "@ledvance/base/src/models/modules/NativePropsSlice";
5
+ import {useNavigation} from '@react-navigation/native'
6
+ import {SwitchButton, Utils} from "tuya-panel-kit";
7
+ import LdvPickerView from "@ledvance/base/src/components/ldvPickerView";
8
+ import I18n from '@ledvance/base/src/i18n'
9
+ import {defSwitchInching, SwitchInchingItem, SwitchInchingPageParams, useSwitchInching} from "./SwitchInchingAction";
10
+ import ThemeType from '@ledvance/base/src/config/themeType'
11
+ import Segmented from "@ledvance/base/src/components/Segmented";
12
+ import Spacer from "@ledvance/base/src/components/Spacer";
13
+ import { useParams } from "@ledvance/base/src/hooks/Hooks";
14
+
15
+ const { convertX: cx } = Utils.RatioUtils
16
+ const { withTheme } = Utils.ThemeUtils
17
+
18
+ const SwitchInching = (props: { theme?: ThemeType }) => {
19
+ const params = useParams<SwitchInchingPageParams>()
20
+ const uaGroupInfo = useUAGroupInfo()
21
+ const navigation = useNavigation()
22
+ const [switchInching, setSwitchInching] = useSwitchInching()
23
+ const timeRef = useRef({
24
+ minute: '00',
25
+ second: '00',
26
+ })
27
+ const [state, setState] = useState({
28
+ loading: false,
29
+ channel: 0,
30
+ switchInchingItem: defSwitchInching[0]
31
+ })
32
+
33
+ const updateState = (newState: Partial<typeof state>) => {
34
+ setState(prev => ({ ...prev, ...newState }));
35
+ };
36
+
37
+ const updateTime = (minute?: string, second?: string) => {
38
+ if (minute !== undefined) timeRef.current.minute = minute;
39
+ if (second !== undefined) timeRef.current.second = second;
40
+
41
+ if (!Number(timeRef.current.minute) && Number(timeRef.current.second) < 1) {
42
+ timeRef.current.second = '01';
43
+ }
44
+
45
+ if (Number(timeRef.current.minute) === 60) {
46
+ timeRef.current.second = '00';
47
+ }
48
+
49
+ const time = Number(timeRef.current.minute) * 60 + Number(timeRef.current.second);
50
+ const newSwitchInchingItem = {
51
+ ...state.switchInchingItem,
52
+ time
53
+ };
54
+
55
+ updateState({ switchInchingItem: newSwitchInchingItem });
56
+
57
+ };
58
+
59
+ const switchInchingItem = useMemo(() => {
60
+ return switchInching.find(item => item.channel === state.channel) ?? { ...defSwitchInching[0], channel: state.channel }
61
+ }, [state.channel, JSON.stringify(switchInching)])
62
+
63
+ useEffect(() => {
64
+ const { minute, second } = formateValue(switchInchingItem)
65
+ timeRef.current = { minute, second }
66
+ updateState({ switchInchingItem })
67
+ }, [switchInchingItem])
68
+
69
+ const saveInchingConfig = async (item: SwitchInchingItem) => {
70
+ const updatedSwitchInching = [...switchInching];
71
+ const existingItemIndex = updatedSwitchInching.findIndex(item => item.channel === state.channel);
72
+ if (existingItemIndex === -1) {
73
+ updatedSwitchInching.push(item);
74
+ } else {
75
+ updatedSwitchInching[existingItemIndex] = item;
76
+ }
77
+ await setSwitchInching(updatedSwitchInching)
78
+ }
79
+
80
+ const formateValue = (switchInchingItem: SwitchInchingItem) => {
81
+ const minute = Math.floor((switchInchingItem.time || 0) / 60).toString().padStart(2, '0')
82
+ const second = ((switchInchingItem.time || 0) % 60).toString().padStart(2, '0')
83
+ return { minute, second }
84
+ }
85
+
86
+ const styles = StyleSheet.create({
87
+ switchContainer: {
88
+ backgroundColor: props.theme?.container.background,
89
+ marginHorizontal: cx(24),
90
+ padding: cx(10),
91
+ borderRadius: cx(6),
92
+ flexDirection: 'column',
93
+ },
94
+ switchCardContainer: {
95
+ paddingVertical: cx(4),
96
+ paddingHorizontal: cx(10),
97
+ backgroundColor: props.theme?.global.background,
98
+ flexDirection: 'row',
99
+ justifyContent: 'center',
100
+ alignItems: 'center',
101
+ borderRadius: cx(6),
102
+ },
103
+ switchCardTitle: {
104
+ color: props.theme?.global.fontColor,
105
+ fontSize: cx(14),
106
+ flex: 1,
107
+ fontWeight: '400',
108
+ },
109
+ switchDescription: {
110
+ color: props.theme?.global.fontColor,
111
+ flexWrap: 'wrap',
112
+ fontSize: cx(12),
113
+ marginTop: cx(4),
114
+ },
115
+ secondTopic: {
116
+ color: props.theme?.global.fontColor,
117
+ flexWrap: 'wrap',
118
+ fontSize: cx(14),
119
+ marginTop: cx(30),
120
+ marginHorizontal: cx(24),
121
+ },
122
+ pickContainer: {
123
+ position: 'relative',
124
+ marginVertical: cx(24),
125
+ marginHorizontal: cx(24),
126
+ },
127
+ disabledCover: {
128
+ position: 'absolute',
129
+ width: '100%',
130
+ height: '100%',
131
+ left: 0,
132
+ top: 0,
133
+ zIndex: 999,
134
+ },
135
+ })
136
+
137
+ return (
138
+ <Page
139
+ backText={uaGroupInfo.name}
140
+ onBackClick={navigation.goBack}
141
+ headlineText={I18n.getLang('sockets_specific_settings_switch_inching')}
142
+ >
143
+ <ScrollView nestedScrollEnabled={true}>
144
+ {params.channelConfig && params.channelConfig.length > 1 && <>
145
+ <Segmented
146
+ style={{ marginHorizontal: cx(24) }}
147
+ options={params.channelConfig.map(item => ({
148
+ label: item.channelTitle,
149
+ value: item.channel
150
+ }))}
151
+ value={state.channel}
152
+ onChange={v => {
153
+ updateState({ channel: Number(v) })
154
+ }}
155
+ />
156
+ <Spacer />
157
+ </>}
158
+ <View style={styles.switchContainer}>
159
+ <View style={styles.switchCardContainer}>
160
+ <Text style={styles.switchCardTitle}>
161
+ {I18n.getLang('socket_settings_switch_off_firstbox_text')}
162
+ </Text>
163
+ <SwitchButton
164
+ value={state.switchInchingItem.enable}
165
+ onValueChange={async v => {
166
+ const time = Number(timeRef.current.minute) * 60 + Number(timeRef.current.second)
167
+ const newSwitchInchingItem = {
168
+ ...state.switchInchingItem,
169
+ enable: v,
170
+ time
171
+ }
172
+ updateState({ switchInchingItem: newSwitchInchingItem })
173
+ await saveInchingConfig(newSwitchInchingItem)
174
+ }}
175
+ />
176
+ </View>
177
+ <Text style={styles.switchDescription}>
178
+ {I18n.getLang('switchinching_overview_description_text')}
179
+ </Text>
180
+ </View>
181
+ <Text style={styles.secondTopic}>
182
+ {I18n.getLang('socket_settings_switch_off_secondtopic')}
183
+ </Text>
184
+ <View style={styles.pickContainer}>
185
+ {state.switchInchingItem.enable && <View style={styles.disabledCover} />}
186
+ <LdvPickerView
187
+ hour={timeRef.current.minute}
188
+ minute={timeRef.current.second}
189
+ unit={[
190
+ I18n.getLang('socket_settings_switch_off_min'),
191
+ I18n.getLang('socket_settings_switch_off_s'),
192
+ ]}
193
+ setHour={m => updateTime(m, undefined)}
194
+ setMinute={s => updateTime(undefined, s)}
195
+ maxHour={61}
196
+ />
197
+ </View>
198
+ </ScrollView>
199
+ </Page>
200
+ );
201
+ };
202
+
203
+ export default withTheme(SwitchInching)
@@ -0,0 +1,60 @@
1
+ import {Buffer} from 'buffer'
2
+ import {Result} from "@ledvance/base/src/models/modules/Result"
3
+ import {useFeatureHook} from "@ledvance/base/src/models/modules/NativePropsSlice";
4
+ import { useMemo } from 'react';
5
+
6
+ interface SwitchInchingConfig {
7
+ switchInching: SwitchInchingItem[]
8
+ }
9
+
10
+ export interface SwitchInchingItem {
11
+ channel: number,
12
+ enable: boolean,
13
+ time: number
14
+ }
15
+
16
+ export interface SwitchInchingPageParams {
17
+ channelConfig?: {
18
+ channelTitle: string
19
+ channel: number
20
+ }[]
21
+ }
22
+
23
+ export const defSwitchInching = [{ enable: false, channel: 0, time: 1 }]
24
+
25
+ export const useSwitchInching = (): [SwitchInchingItem[], (v: SwitchInchingItem[]) => Promise<Result<any>>] => {
26
+ const [switchInching, setSwitchInching] = useFeatureHook<SwitchInchingConfig, SwitchInchingItem[]>('switchInching', defSwitchInching, modes => {
27
+ const buffers = modes.map(mode => {
28
+ const buffer = new Uint8Array(3)
29
+ // 第1个字节:开/关+通道号
30
+ buffer[0] = packOnOffChannel(mode.enable, mode.channel)
31
+ // 第2、3个字节:点动时间
32
+ buffer[1] = (mode.time >> 8) & 0xff
33
+ buffer[2] = mode.time & 0xff
34
+ return buffer
35
+ })
36
+ const combinedBuffer = new Uint8Array(buffers.length * 3)
37
+ buffers.forEach((buffer, index) => {
38
+ combinedBuffer.set(buffer, index * 3)
39
+ })
40
+ return Buffer.from(combinedBuffer).toString('base64')
41
+ })
42
+
43
+
44
+ const newSwitchInching = useMemo(() => {
45
+ if (typeof switchInching === 'object' && !Array.isArray(switchInching)) {
46
+ const item = JSON.parse(JSON.stringify(switchInching))
47
+ return [{ ...item, channel: 0 }]
48
+ }
49
+ return switchInching
50
+ }, [switchInching])
51
+
52
+ return [newSwitchInching, setSwitchInching]
53
+ }
54
+
55
+ // 工具函数:将开/关和通道号打包为一个字节
56
+ function packOnOffChannel(enable: boolean, channel: number = 0): number {
57
+ const enableBit = enable ? 1 : 0;
58
+ const channelBits = (channel << 1) & 0b11111110;
59
+ return enableBit | channelBits;
60
+ }
@@ -1,172 +0,0 @@
1
- import React, {useEffect} from "react";
2
- import {StyleSheet, Text, View} from "react-native";
3
- import Page from "@ledvance/base/src/components/Page";
4
- import {useUAGroupInfo} from "@ledvance/base/src/models/modules/NativePropsSlice";
5
- import {useNavigation} from '@react-navigation/native'
6
- import {SwitchButton, Utils} from "tuya-panel-kit";
7
- import LdvPickerView from "@ledvance/base/src/components/ldvPickerView";
8
- import I18n from '@ledvance/base/src/i18n'
9
- import {useReactive, useUpdateEffect} from "ahooks";
10
- import {useSwitchInching} from "./SwithInchingAction";
11
- import ThemeType from '@ledvance/base/src/config/themeType'
12
-
13
- const {convertX: cx} = Utils.RatioUtils
14
- const { withTheme } = Utils.ThemeUtils
15
-
16
- interface SwitchInchingState {
17
- enable: boolean,
18
- minute: string,
19
- second: string,
20
- flag: Symbol | number
21
- }
22
-
23
- const SwitchInching = (props: { theme?: ThemeType }) => {
24
- const uaGroupInfo = useUAGroupInfo()
25
- const navigation = useNavigation()
26
- const [switchInching, setSwitchInching] = useSwitchInching()
27
-
28
- const state = useReactive<SwitchInchingState>({
29
- enable: false,
30
- minute: '00',
31
- second: '00',
32
- flag: 1
33
- })
34
-
35
- useEffect(() => {
36
- state.enable = switchInching.enable
37
- state.minute = formatValue('minute')
38
- state.second = formatValue('second')
39
- }, [JSON.stringify(switchInching)])
40
-
41
-
42
- const requestSwitchInching = () => {
43
- const enable = state.enable
44
- const time = Number(state.minute) * 60 + Number(state.second)
45
- setSwitchInching({enable, time}).then(_r => {})
46
- }
47
-
48
- useEffect(() => {
49
- if (state.flag !== 1) {
50
- requestSwitchInching()
51
- }
52
- }, [state.flag])
53
-
54
- useUpdateEffect(() => {
55
- if (!Number(state.minute) && Number(state.second) < 2) {
56
- state.second = '02'
57
- }
58
- if (Number(state.minute) === 60) {
59
- state.second = '00'
60
- }
61
- }, [state.minute, state.second])
62
-
63
- const formatValue = (type: string) => {
64
- const m = parseInt(String((switchInching?.time || 0) / 60))
65
- if (type === 'minute') {
66
- return m.toString().padStart(2, '0')
67
- } else {
68
- const s = switchInching.time - 60 * m
69
- return s === 0 ? '00' : s < 10 ? '0' + s : String(s)
70
- }
71
- }
72
-
73
- const styles = StyleSheet.create({
74
- switchContainer: {
75
- backgroundColor: props.theme?.container.background,
76
- marginHorizontal: cx(24),
77
- padding: cx(10),
78
- borderRadius: cx(6),
79
- flexDirection: 'column',
80
- },
81
- switchCardContainer: {
82
- paddingVertical: cx(4),
83
- paddingHorizontal: cx(10),
84
- backgroundColor: props.theme?.global.background,
85
- flexDirection: 'row',
86
- justifyContent: 'center',
87
- alignItems: 'center',
88
- borderRadius: cx(6),
89
- },
90
- switchCardTitle: {
91
- color: props.theme?.global.fontColor,
92
- fontSize: cx(14),
93
- flex: 1,
94
- fontWeight: '400',
95
- },
96
- switchDescription: {
97
- color: props.theme?.global.fontColor,
98
- flexWrap: 'wrap',
99
- fontSize: cx(12),
100
- marginTop: cx(4),
101
- },
102
- secondTopic: {
103
- color: props.theme?.global.fontColor,
104
- flexWrap: 'wrap',
105
- fontSize: cx(14),
106
- marginTop: cx(30),
107
- marginHorizontal: cx(24),
108
- },
109
- pickContainer: {
110
- position: 'relative',
111
- marginVertical: cx(24),
112
- marginHorizontal: cx(24),
113
- },
114
- disabledCover: {
115
- position: 'absolute',
116
- width: '100%',
117
- height: '100%',
118
- left: 0,
119
- top: 0,
120
- zIndex: 999,
121
- },
122
- })
123
-
124
- return (
125
- <Page
126
- backText={uaGroupInfo.name}
127
- onBackClick={navigation.goBack}
128
- headlineText={I18n.getLang('socket_settings_switch_off_firstbox_text')}
129
- >
130
- <View style={styles.switchContainer}>
131
- <View style={styles.switchCardContainer}>
132
- <Text style={styles.switchCardTitle}>
133
- {I18n.getLang('socket_settings_switch_off_firstbox_text')}
134
- </Text>
135
- <SwitchButton
136
- value={switchInching.enable}
137
- onValueChange={v => {
138
- state.enable = v
139
- state.flag = Symbol()
140
- }}
141
- />
142
- </View>
143
- <Text style={styles.switchDescription}>
144
- {I18n.getLang('switchinching_overview_description_text')}
145
- </Text>
146
- </View>
147
- <Text style={styles.secondTopic}>
148
- {I18n.getLang('socket_settings_switch_off_secondtopic')}
149
- </Text>
150
- <View style={styles.pickContainer}>
151
- {switchInching.enable && <View style={styles.disabledCover}/>}
152
- <LdvPickerView
153
- maxHour={61}
154
- hour={state.minute}
155
- minute={state.second}
156
- unit={[
157
- I18n.getLang('socket_settings_switch_off_min'),
158
- I18n.getLang('socket_settings_switch_off_s'),
159
- ]}
160
- setHour={m => {
161
- state.minute = m
162
- }}
163
- setMinute={s => {
164
- state.second = s
165
- }}
166
- />
167
- </View>
168
- </Page>
169
- )
170
- }
171
-
172
- export default withTheme(SwitchInching)
@@ -1,32 +0,0 @@
1
- import {Buffer} from 'buffer'
2
- import {Result} from "@ledvance/base/src/models/modules/Result"
3
- import {useFeatureHook} from "@ledvance/base/src/models/modules/NativePropsSlice";
4
-
5
- interface SwitchInchingConfig {
6
- switchInching: SwitchInchingModel
7
- }
8
-
9
- interface SwitchInchingModel {
10
- enable: boolean
11
- channel?: number
12
- time: number
13
- }
14
-
15
- export const useSwitchInching = (): [SwitchInchingModel, (v: SwitchInchingModel) => Promise<Result<any>>] => {
16
- return useFeatureHook<SwitchInchingConfig, SwitchInchingModel>('switchInching', {enable: false, channel: 0, time: 1}, mode => {
17
- const buffer = new Uint8Array(3)
18
- // 第1个字节:开/关+通道号
19
- buffer[0] = packOnOffChannel(mode.enable, mode.channel)
20
- // 第2、3个字节:点动时间
21
- buffer[1] = (mode.time >> 8) & 0xff
22
- buffer[2] = mode.time & 0xff
23
- return Buffer.from(buffer).toString('base64')
24
- })
25
- }
26
-
27
- // 工具函数:将开/关和通道号打包为一个字节
28
- function packOnOffChannel(enable: boolean, channel: number = 0): number {
29
- const enableBit = enable ? 1 : 0;
30
- const channelBits = (channel << 1) & 0b11111110;
31
- return enableBit | channelBits;
32
- }