Commit 8ee1c779 authored by sliao's avatar sliao

feat: sdm

parent 5e3ddf56
......@@ -2,3 +2,4 @@ node_modules
.ray
dist
app.config.ts
.DS_Store
\ No newline at end of file
......@@ -12,6 +12,8 @@
"@ray-js/panel-sdk": "^1.1.3",
"@ray-js/ray": "^0.6.13",
"@ray-js/sdm-react": "^1.0.6",
"@tuya-miniapp/sdm": "^1.1.0-beta.0",
"clsx": "^1.2.1",
"deep-object-diff": "^1.1.0",
"react-redux": "^7.2.1",
"redux": "^4.1.2",
......@@ -2692,6 +2694,33 @@
"node": ">=0.8.0"
}
},
"node_modules/@emotion/is-prop-valid": {
"version": "1.2.0",
"resolved": "https://registry.npmmirror.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz",
"integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==",
"peer": true,
"dependencies": {
"@emotion/memoize": "^0.8.0"
}
},
"node_modules/@emotion/memoize": {
"version": "0.8.0",
"resolved": "https://registry.npmmirror.com/@emotion/memoize/-/memoize-0.8.0.tgz",
"integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==",
"peer": true
},
"node_modules/@emotion/stylis": {
"version": "0.8.5",
"resolved": "https://registry.npmmirror.com/@emotion/stylis/-/stylis-0.8.5.tgz",
"integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==",
"peer": true
},
"node_modules/@emotion/unitless": {
"version": "0.7.5",
"resolved": "https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.7.5.tgz",
"integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==",
"peer": true
},
"node_modules/@eslint/eslintrc": {
"version": "0.4.3",
"resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
......@@ -10233,6 +10262,21 @@
"asap": "~2.0.3"
}
},
"node_modules/@ray-js/ray-panel-utils/node_modules/react": {
"version": "16.8.3",
"resolved": "https://registry.npmmirror.com/react/-/react-16.8.3.tgz",
"integrity": "sha512-3UoSIsEq8yTJuSu0luO1QQWYbgGEILm+eJl2QN/VLDi7hL+EN18M3q3oVZwmVzzBJ3DkM7RMdRwBmZZ+b4IzSA==",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
"scheduler": "^0.13.3"
},
"engines": {
"node": ">=0.10.0"
}
},
"node_modules/@ray-js/ray-panel-utils/node_modules/react-devtools-core": {
"version": "3.6.3",
"resolved": "https://registry.npmmirror.com/react-devtools-core/-/react-devtools-core-3.6.3.tgz",
......@@ -10728,6 +10772,16 @@
"node": ">=0.10.0"
}
},
"node_modules/@ray-js/ray-panel-utils/node_modules/scheduler": {
"version": "0.13.6",
"resolved": "https://registry.npmmirror.com/scheduler/-/scheduler-0.13.6.tgz",
"integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==",
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
}
},
"node_modules/@ray-js/ray-panel-utils/node_modules/semver": {
"version": "5.7.1",
"resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.1.tgz",
......@@ -13297,23 +13351,15 @@
"@ray-js/api": "^0.3.28"
}
},
"node_modules/@ray-js/sdm-react/node_modules/use-context-selector": {
"version": "1.4.1",
"resolved": "https://registry.npmmirror.com/use-context-selector/-/use-context-selector-1.4.1.tgz",
"integrity": "sha512-Io2ArvcRO+6MWIhkdfMFt+WKQX+Vb++W8DS2l03z/Vw/rz3BclKpM0ynr4LYGyU85Eke+Yx5oIhTY++QR0ZDoA==",
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": "*",
"react-native": "*",
"scheduler": ">=0.19.0"
"node_modules/@ray-js/sdm-react/node_modules/@tuya-miniapp/sdm": {
"version": "1.0.5",
"resolved": "https://registry.npmmirror.com/@tuya-miniapp/sdm/-/sdm-1.0.5.tgz",
"integrity": "sha512-RYzGLG0LxUnOfQSOzUtzjaF3AdlFgDQ3SJN8I4lMUwJgQwKA54M/jIzDMYlUH7fiQc8jCPlIkMsqzI8B3IbgCQ==",
"dependencies": {
"@ray-js/panel-sdk": "^1.1.4"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
}
"peerDependencies": {
"@ray-js/api": "^0.3.28"
}
},
"node_modules/@ray-js/shared": {
......@@ -14164,11 +14210,11 @@
"peer": true
},
"node_modules/@tuya-miniapp/sdm": {
"version": "1.0.5",
"resolved": "https://registry.npmmirror.com/@tuya-miniapp/sdm/-/sdm-1.0.5.tgz",
"integrity": "sha512-RYzGLG0LxUnOfQSOzUtzjaF3AdlFgDQ3SJN8I4lMUwJgQwKA54M/jIzDMYlUH7fiQc8jCPlIkMsqzI8B3IbgCQ==",
"version": "1.1.0-beta.0",
"resolved": "https://registry.npmmirror.com/@tuya-miniapp/sdm/-/sdm-1.1.0-beta.0.tgz",
"integrity": "sha512-gHlO5RidaCTXx3AidxCJyrY6FuNgV70eAwpMYmqfB6qbf/TOe2YPaOQVIyowjkrfYD9/jzC5v2Da7wceHlhM9w==",
"dependencies": {
"@ray-js/panel-sdk": "^1.1.4"
"@ray-js/panel-sdk": "^1.1.3"
},
"peerDependencies": {
"@ray-js/api": "^0.3.28"
......@@ -16403,6 +16449,28 @@
"@babel/core": "^7.0.0-0"
}
},
"node_modules/babel-plugin-styled-components": {
"version": "2.0.7",
"resolved": "https://registry.npmmirror.com/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.7.tgz",
"integrity": "sha512-i7YhvPgVqRKfoQ66toiZ06jPNA3p6ierpfUuEWxNF+fV27Uv5gxBkf8KZLHUCc1nFA9j6+80pYoIpqCeyW3/bA==",
"peer": true,
"dependencies": {
"@babel/helper-annotate-as-pure": "^7.16.0",
"@babel/helper-module-imports": "^7.16.0",
"babel-plugin-syntax-jsx": "^6.18.0",
"lodash": "^4.17.11",
"picomatch": "^2.3.0"
},
"peerDependencies": {
"styled-components": ">= 2"
}
},
"node_modules/babel-plugin-syntax-jsx": {
"version": "6.18.0",
"resolved": "https://registry.npmmirror.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
"integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==",
"peer": true
},
"node_modules/babel-plugin-syntax-trailing-function-commas": {
"version": "7.0.0-beta.0",
"resolved": "https://registry.npmmirror.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz",
......@@ -17493,7 +17561,6 @@
"version": "1.2.1",
"resolved": "https://registry.npmmirror.com/clsx/-/clsx-1.2.1.tgz",
"integrity": "sha512-EcR6r5a8bj6pu3ycsa/E/cKVGuTgZJZdsyUYHOksG/UHIiKfjxzRxYJpyVBwYaQeOvghal9fcc4PidlgzugAQg==",
"license": "MIT",
"engines": {
"node": ">=6"
}
......@@ -29161,7 +29228,6 @@
"version": "4.2.0",
"resolved": "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
"dev": true,
"license": "MIT"
},
"node_modules/postcss-values-parser": {
......@@ -29601,7 +29667,6 @@
"version": "16.14.0",
"resolved": "https://registry.npmmirror.com/react-dom/-/react-dom-16.14.0.tgz",
"integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==",
"devOptional": true,
"peer": true,
"dependencies": {
"loose-envify": "^1.1.0",
......@@ -31951,6 +32016,65 @@
"inline-style-parser": "0.1.1"
}
},
"node_modules/styled-components": {
"version": "5.3.6",
"resolved": "https://registry.npmmirror.com/styled-components/-/styled-components-5.3.6.tgz",
"integrity": "sha512-hGTZquGAaTqhGWldX7hhfzjnIYBZ0IXQXkCYdvF1Sq3DsUaLx6+NTHC5Jj1ooM2F68sBiVz3lvhfwQs/S3l6qg==",
"hasInstallScript": true,
"peer": true,
"dependencies": {
"@babel/helper-module-imports": "^7.0.0",
"@babel/traverse": "^7.4.5",
"@emotion/is-prop-valid": "^1.1.0",
"@emotion/stylis": "^0.8.4",
"@emotion/unitless": "^0.7.4",
"babel-plugin-styled-components": ">= 1.12.0",
"css-to-react-native": "^3.0.0",
"hoist-non-react-statics": "^3.0.0",
"shallowequal": "^1.1.0",
"supports-color": "^5.5.0"
},
"engines": {
"node": ">=10"
},
"peerDependencies": {
"react": ">= 16.8.0",
"react-dom": ">= 16.8.0",
"react-is": ">= 16.8.0"
}
},
"node_modules/styled-components/node_modules/css-to-react-native": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz",
"integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==",
"peer": true,
"dependencies": {
"camelize": "^1.0.0",
"css-color-keywords": "^1.0.0",
"postcss-value-parser": "^4.0.2"
}
},
"node_modules/styled-components/node_modules/has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"peer": true,
"engines": {
"node": ">=4"
}
},
"node_modules/styled-components/node_modules/supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"peer": true,
"dependencies": {
"has-flag": "^3.0.0"
},
"engines": {
"node": ">=4"
}
},
"node_modules/stylis": {
"version": "3.5.4",
"resolved": "https://registry.npmmirror.com/stylis/-/stylis-3.5.4.tgz",
......@@ -35281,6 +35405,25 @@
"node": ">=0.10.0"
}
},
"node_modules/use-context-selector": {
"version": "1.4.1",
"resolved": "https://registry.npmmirror.com/use-context-selector/-/use-context-selector-1.4.1.tgz",
"integrity": "sha512-Io2ArvcRO+6MWIhkdfMFt+WKQX+Vb++W8DS2l03z/Vw/rz3BclKpM0ynr4LYGyU85Eke+Yx5oIhTY++QR0ZDoA==",
"peerDependencies": {
"react": ">=16.8.0",
"react-dom": "*",
"react-native": "*",
"scheduler": ">=0.19.0"
},
"peerDependenciesMeta": {
"react-dom": {
"optional": true
},
"react-native": {
"optional": true
}
}
},
"node_modules/use-latest-callback": {
"version": "0.1.5",
"resolved": "https://registry.npmmirror.com/use-latest-callback/-/use-latest-callback-0.1.5.tgz",
......@@ -38453,6 +38596,33 @@
"@types/hammerjs": "^2.0.36"
}
},
"@emotion/is-prop-valid": {
"version": "1.2.0",
"resolved": "https://registry.npmmirror.com/@emotion/is-prop-valid/-/is-prop-valid-1.2.0.tgz",
"integrity": "sha512-3aDpDprjM0AwaxGE09bOPkNxHpBd+kA6jty3RnaEXdweX1DF1U3VQpPYb0g1IStAuK7SVQ1cy+bNBBKp4W3Fjg==",
"peer": true,
"requires": {
"@emotion/memoize": "^0.8.0"
}
},
"@emotion/memoize": {
"version": "0.8.0",
"resolved": "https://registry.npmmirror.com/@emotion/memoize/-/memoize-0.8.0.tgz",
"integrity": "sha512-G/YwXTkv7Den9mXDO7AhLWkE3q+I92B+VqAE+dYG4NGPaHZGvt3G8Q0p9vmE+sq7rTGphUbAvmQ9YpbfMQGGlA==",
"peer": true
},
"@emotion/stylis": {
"version": "0.8.5",
"resolved": "https://registry.npmmirror.com/@emotion/stylis/-/stylis-0.8.5.tgz",
"integrity": "sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ==",
"peer": true
},
"@emotion/unitless": {
"version": "0.7.5",
"resolved": "https://registry.npmmirror.com/@emotion/unitless/-/unitless-0.7.5.tgz",
"integrity": "sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg==",
"peer": true
},
"@eslint/eslintrc": {
"version": "0.4.3",
"resolved": "https://registry.npmmirror.com/@eslint/eslintrc/-/eslintrc-0.4.3.tgz",
......@@ -44680,6 +44850,18 @@
"asap": "~2.0.3"
}
},
"react": {
"version": "16.8.3",
"resolved": "https://registry.npmmirror.com/react/-/react-16.8.3.tgz",
"integrity": "sha512-3UoSIsEq8yTJuSu0luO1QQWYbgGEILm+eJl2QN/VLDi7hL+EN18M3q3oVZwmVzzBJ3DkM7RMdRwBmZZ+b4IzSA==",
"peer": true,
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1",
"prop-types": "^15.6.2",
"scheduler": "^0.13.3"
}
},
"react-devtools-core": {
"version": "3.6.3",
"resolved": "https://registry.npmmirror.com/react-devtools-core/-/react-devtools-core-3.6.3.tgz",
......@@ -45096,6 +45278,16 @@
}
}
},
"scheduler": {
"version": "0.13.6",
"resolved": "https://registry.npmmirror.com/scheduler/-/scheduler-0.13.6.tgz",
"integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==",
"peer": true,
"requires": {
"loose-envify": "^1.1.0",
"object-assign": "^4.1.1"
}
},
"semver": {
"version": "5.7.1",
"resolved": "https://registry.npmmirror.com/semver/-/semver-5.7.1.tgz",
......@@ -47247,11 +47439,13 @@
"use-context-selector": "^1.4.1"
},
"dependencies": {
"use-context-selector": {
"version": "1.4.1",
"resolved": "https://registry.npmmirror.com/use-context-selector/-/use-context-selector-1.4.1.tgz",
"integrity": "sha512-Io2ArvcRO+6MWIhkdfMFt+WKQX+Vb++W8DS2l03z/Vw/rz3BclKpM0ynr4LYGyU85Eke+Yx5oIhTY++QR0ZDoA==",
"requires": {}
"@tuya-miniapp/sdm": {
"version": "1.0.5",
"resolved": "https://registry.npmmirror.com/@tuya-miniapp/sdm/-/sdm-1.0.5.tgz",
"integrity": "sha512-RYzGLG0LxUnOfQSOzUtzjaF3AdlFgDQ3SJN8I4lMUwJgQwKA54M/jIzDMYlUH7fiQc8jCPlIkMsqzI8B3IbgCQ==",
"requires": {
"@ray-js/panel-sdk": "^1.1.4"
}
}
}
},
......@@ -47980,11 +48174,11 @@
"peer": true
},
"@tuya-miniapp/sdm": {
"version": "1.0.5",
"resolved": "https://registry.npmmirror.com/@tuya-miniapp/sdm/-/sdm-1.0.5.tgz",
"integrity": "sha512-RYzGLG0LxUnOfQSOzUtzjaF3AdlFgDQ3SJN8I4lMUwJgQwKA54M/jIzDMYlUH7fiQc8jCPlIkMsqzI8B3IbgCQ==",
"version": "1.1.0-beta.0",
"resolved": "https://registry.npmmirror.com/@tuya-miniapp/sdm/-/sdm-1.1.0-beta.0.tgz",
"integrity": "sha512-gHlO5RidaCTXx3AidxCJyrY6FuNgV70eAwpMYmqfB6qbf/TOe2YPaOQVIyowjkrfYD9/jzC5v2Da7wceHlhM9w==",
"requires": {
"@ray-js/panel-sdk": "^1.1.4"
"@ray-js/panel-sdk": "^1.1.3"
}
},
"@tuya-miniapp/ty-kit": {
......@@ -49676,6 +49870,25 @@
"@babel/helper-define-polyfill-provider": "^0.3.3"
}
},
"babel-plugin-styled-components": {
"version": "2.0.7",
"resolved": "https://registry.npmmirror.com/babel-plugin-styled-components/-/babel-plugin-styled-components-2.0.7.tgz",
"integrity": "sha512-i7YhvPgVqRKfoQ66toiZ06jPNA3p6ierpfUuEWxNF+fV27Uv5gxBkf8KZLHUCc1nFA9j6+80pYoIpqCeyW3/bA==",
"peer": true,
"requires": {
"@babel/helper-annotate-as-pure": "^7.16.0",
"@babel/helper-module-imports": "^7.16.0",
"babel-plugin-syntax-jsx": "^6.18.0",
"lodash": "^4.17.11",
"picomatch": "^2.3.0"
}
},
"babel-plugin-syntax-jsx": {
"version": "6.18.0",
"resolved": "https://registry.npmmirror.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz",
"integrity": "sha512-qrPaCSo9c8RHNRHIotaufGbuOBN8rtdC4QrrFFc43vyWCCz7Kl7GL1PGaXtMGQZUXrkCjNEgxDfmAuAabr/rlw==",
"peer": true
},
"babel-plugin-syntax-trailing-function-commas": {
"version": "7.0.0-beta.0",
"resolved": "https://registry.npmmirror.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-7.0.0-beta.0.tgz",
......@@ -59108,8 +59321,7 @@
"postcss-value-parser": {
"version": "4.2.0",
"resolved": "https://registry.npmmirror.com/postcss-value-parser/-/postcss-value-parser-4.2.0.tgz",
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ==",
"dev": true
"integrity": "sha512-1NNCs6uurfkVbeXG4S8JFT9t19m45ICnif8zWLd5oPSZ50QnwMfK+H3jv408d4jw/7Bttv5axS5IiHoLaVNHeQ=="
},
"postcss-values-parser": {
"version": "2.0.1",
......@@ -59422,7 +59634,6 @@
"version": "16.14.0",
"resolved": "https://registry.npmmirror.com/react-dom/-/react-dom-16.14.0.tgz",
"integrity": "sha512-1gCeQXDLoIqMgqD3IO2Ah9bnf0w9kzhwN5q4FGnHZ67hBm9yePzB5JJAIQCc8x3pFnNlwFq4RidZggNAAkzWWw==",
"devOptional": true,
"peer": true,
"requires": {
"loose-envify": "^1.1.0",
......@@ -61199,6 +61410,52 @@
"inline-style-parser": "0.1.1"
}
},
"styled-components": {
"version": "5.3.6",
"resolved": "https://registry.npmmirror.com/styled-components/-/styled-components-5.3.6.tgz",
"integrity": "sha512-hGTZquGAaTqhGWldX7hhfzjnIYBZ0IXQXkCYdvF1Sq3DsUaLx6+NTHC5Jj1ooM2F68sBiVz3lvhfwQs/S3l6qg==",
"peer": true,
"requires": {
"@babel/helper-module-imports": "^7.0.0",
"@babel/traverse": "^7.4.5",
"@emotion/is-prop-valid": "^1.1.0",
"@emotion/stylis": "^0.8.4",
"@emotion/unitless": "^0.7.4",
"babel-plugin-styled-components": ">= 1.12.0",
"css-to-react-native": "^3.0.0",
"hoist-non-react-statics": "^3.0.0",
"shallowequal": "^1.1.0",
"supports-color": "^5.5.0"
},
"dependencies": {
"css-to-react-native": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/css-to-react-native/-/css-to-react-native-3.0.0.tgz",
"integrity": "sha512-Ro1yETZA813eoyUp2GDBhG2j+YggidUmzO1/v9eYBKR2EHVEniE2MI/NqpTQ954BMpTPZFsGNPm46qFB9dpaPQ==",
"peer": true,
"requires": {
"camelize": "^1.0.0",
"css-color-keywords": "^1.0.0",
"postcss-value-parser": "^4.0.2"
}
},
"has-flag": {
"version": "3.0.0",
"resolved": "https://registry.npmmirror.com/has-flag/-/has-flag-3.0.0.tgz",
"integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==",
"peer": true
},
"supports-color": {
"version": "5.5.0",
"resolved": "https://registry.npmmirror.com/supports-color/-/supports-color-5.5.0.tgz",
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
"peer": true,
"requires": {
"has-flag": "^3.0.0"
}
}
}
},
"stylis": {
"version": "3.5.4",
"resolved": "https://registry.npmmirror.com/stylis/-/stylis-3.5.4.tgz",
......@@ -63879,6 +64136,12 @@
"resolved": "https://registry.npmmirror.com/use/-/use-3.1.1.tgz",
"integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ=="
},
"use-context-selector": {
"version": "1.4.1",
"resolved": "https://registry.npmmirror.com/use-context-selector/-/use-context-selector-1.4.1.tgz",
"integrity": "sha512-Io2ArvcRO+6MWIhkdfMFt+WKQX+Vb++W8DS2l03z/Vw/rz3BclKpM0ynr4LYGyU85Eke+Yx5oIhTY++QR0ZDoA==",
"requires": {}
},
"use-latest-callback": {
"version": "0.1.5",
"resolved": "https://registry.npmmirror.com/use-latest-callback/-/use-latest-callback-0.1.5.tgz",
......@@ -6,6 +6,7 @@
"scripts": {
"lint": "eslint src --ext .js,.jsx,.ts,.tsx --fix",
"test": "echo \"Error: no test specified\" && exit 1",
"start": "ray start -t tuya --verbose",
"start:native": "ray start -t native --verbose",
"start:tuya": "ray start -t tuya --verbose",
"build:native": "ray build -t native --verbose",
......@@ -15,12 +16,17 @@
"@ray-js/panel-sdk": "^1.1.3",
"@ray-js/ray": "^0.6.13",
"@ray-js/sdm-react": "^1.0.6",
"@tuya-miniapp/sdm": "^1.1.0-beta.0",
"clsx": "^1.2.1",
"deep-object-diff": "^1.1.0",
"react-redux": "^7.2.1",
"redux": "^4.1.2",
"redux-actions": "^2.6.5",
"redux-logger": "^3.0.6",
"redux-thunk": "^2.4.0"
"redux-thunk": "^2.4.0",
"ahooks": "^3.7.1",
"core-js": "^3.23.5",
"dayjs": "^1.11.5"
},
"devDependencies": {
"@commitlint/cli": "^7.2.1",
......@@ -37,7 +43,11 @@
"husky": "^1.2.0",
"lint-staged": "^10.2.11",
"prettier": "^1.16.4",
"typescript": "^4.4.3"
"typescript": "^4.4.3",
"@types/react": "^17.0.24",
"@types/react-dom": "^17.0.9",
"react": "^17.0.2",
"react-dom": "^17.0.2"
},
"husky": {
"hooks": {
......
......@@ -10,5 +10,5 @@
"TYKit": "2.3.4",
"DeviceKit": "2.4.7"
},
"productId": "hcwquhbmkmjatays"
"productId": "88lyidpn8pajyg2o"
}
\ No newline at end of file
......@@ -3,18 +3,30 @@ import { kit } from '@ray-js/panel-sdk';
import 'ray';
import '@/i18n';
import composeLayout from './composeLayout';
import { SdmProvider } from '@ray-js/sdm-react';
import { devices } from '@/devices';
import { ProductName } from '@/constants';
const { initPanelEnvironment } = kit;
interface Props {
children: React.ReactNode
}
initPanelEnvironment({ useDefaultOffline: true });
class App extends React.Component {
class App extends React.Component<Props> {
componentDidMount() {
console.info('app did mount ');
}
onLaunch(e) {
console.info(e, '=== App onLaunch');
}
render() {
return this.props.children;
return <SdmProvider value={devices[ProductName]} >{this.props.children}</SdmProvider>;
}
}
export default composeLayout(App);
export default App
import React from 'react';
import { DpBooleanAction, DpCommonAction } from '@tuya-miniapp/sdm';
import { useSdmProps } from '@ray-js/sdm-react';
import {devices} from '@/devices'
import styles from '../../pages/home/index.module.less';
import { Image, View, Text } from '@ray-js/components'
import horizontalOff from '../../../public/icon-horizontal-off.png'
import horizontalOn from '../../../public/icon-horizontal-on.png'
import verticalOn from '../../../public/icon-vertical-on.png'
import verticalOff from '../../../public/icon-vertical-off.png'
export const FanVertical = React.memo(() => {
const fanHorizontalCode = 'fan_horizontal'
const fanVerticalCode = 'fan_vertical'
const fanVerticalSwitchCode = 'switch_vertical'
const fanHorizontalSwitchCode = 'switch_horizontal'
const fanHorizontalVal = useSdmProps((props) => props[fanHorizontalCode])
const fanVerticalVal = useSdmProps((props) => props[fanVerticalCode])
const fanHorizontalSwitch = useSdmProps((props) => props[fanHorizontalSwitchCode])
const fanVerticalSwitch = useSdmProps((props) => props[fanVerticalSwitchCode])
const device = devices.fan
const actions = device.model.actions
const fanHorizontalAction = actions[fanHorizontalCode] as DpCommonAction<string>
const fanVerticalAction = actions[fanVerticalCode] as DpCommonAction<string>
const fanHorizontalSwitchAction = actions[fanHorizontalSwitchCode] as DpBooleanAction
const fanVerticalSwitchAction = actions[fanVerticalSwitchCode] as DpBooleanAction
const verticalMenu = [
{
title:'Vertical',
icon:verticalOn,
offIcon: verticalOff,
mode:'vertical',
value: fanVerticalVal
}, {
title:'Horizontal',
icon:horizontalOn,
offIcon: horizontalOff,
mode:'horizontal',
value: fanHorizontalVal
}
]
function handleVerticalMenu(index) {
if (index == 0) {
// if (!fanVerticalSwitch) {
// fanVerticalAction.set(String(90))
// fanVerticalSwitchAction.on()
// } else {
// fanVerticalSwitchAction.off()
// }
fanVerticalSwitchAction.toggle()
}else {
// if (!fanHorizontalSwitch) {
// fanHorizontalAction.set(String(90))
// fanHorizontalSwitchAction.on()
// }else {
// fanHorizontalSwitchAction.off()
// }
fanHorizontalSwitchAction.toggle()
}
}
function submenuItem(index, arr = verticalMenu, clickFun = handleVerticalMenu) {
const isOn = index == 0 ? fanVerticalSwitch : fanHorizontalSwitch
const {title, icon, offIcon} = arr[index]
return (
<View className={styles.button}>
<Image className={styles.menuImage} src={isOn ? icon:offIcon} onClick={() => {clickFun(index)}}/>
<Text className={styles.bTitle}>{title}</Text>
</View>
)
}
const clickNum = (val, index) => {
console.log(val, index)
if (index == 0 && fanVerticalSwitch) {
fanVerticalAction.set(String(val))
}else if (index == 1 && fanHorizontalSwitch) {
fanHorizontalAction.set(String(val))
}
}
function verticalItem(index) {
const item = verticalMenu[index]
const isBlack = (index == 0 && fanVerticalSwitch) || (index == 1 && fanHorizontalSwitch)
const textColor = (subIndex) => {
return {color: isBlack && (Number(item.value) == (subIndex * 30)) ? '#000000':'rgba(0,0,0,0.4)',
width:'33.3%',
textAlign:'center',
lineHeight:'64px',
fontWeight:'500'
}}
return (
<View className={styles.verticalItem}>
{submenuItem(index, verticalMenu, handleVerticalMenu)}
<View className={styles.verticalNumBg}>
<View style={textColor(1)} onClick={() => {clickNum(30, index)}}>30</View>
<View style={textColor(2)} onClick={() => {clickNum(60, index)}}>60</View>
<View style={textColor(3)} onClick={() => {clickNum(90, index)}}>90</View>
</View>
</View>
)
}
return (
<View>
{
verticalItem(0)
}
{
verticalItem(1)
}
</View>
)
})
\ No newline at end of file
export { default as Connect } from './connect';
export { LightPanel } from './light-panel';
export {FanVertical} from './fan-vertical';
\ No newline at end of file
.lightModal {
display: flex;
flex-direction: column;
// margin: auto;
width: 340px;
height: 424px;
background-color: white;
border-radius: 24px;
// position: absolute;
// top: calc(50vh - 175px);
margin-top: 90px;
padding: 20px 0 40px;
color: #000000;
z-index: 9999;
}
.lightModalTop {
display: flex;
align-items: center;
padding: 0 20px;
width: 100%;
justify-content: space-between;
font-size: 16px;
margin-bottom: 40px;
}
.lightModalClose {
width: 24px;
height: 24px;
}
.lightMiddle {
// width: 100%;
height: 155px;
border-radius: 16px 16px 0 0;
background: linear-gradient(-90deg, #cdecfe 0%, #ffffff 45.46%, #ffffff 53.61%, #ffca5c 100%);
position: relative;
margin: 0 3px;
}
.modalback {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 99;
display: flex;
// align-items: center;
justify-content: center;
}
.moveCircle {
width: 28px;
height: 28px;
border: 3px solid #ffffff;
border-radius: 14px;
position: absolute;
background-color: #ffca5c;
z-index: 10001;
}
.progressBg {
// width: 100%;
height: 40px;
border-radius: 0 0 16px 16px;
background-color: #e5e5e5;
display: flex;
align-items: center;
padding-left: 16px;
font-size: 16px;
position: relative;
overflow: hidden;
margin: 0 3px;
}
.progressSun {
width: 21px;
height: 21px;
margin-right: 9px;
z-index: 9999;
}
.progressTitle {
z-index: 9999;
}
.progressBar {
background-color: white;
position: absolute;
left: 1px;
top: 1px;
bottom: 1px;
z-index: 2;
}
.lightBtn {
width: 310px;
height: 56px;
border-radius: 24px;
align-items: center;
justify-content: center;
display: flex;
background-color: rgba(0, 0, 0, 0.5);
align-self: center;
margin-top: 48px;
}
.lightBtnIcon {
width: 18px;
height: 26px;
margin-right: 14px;
}
.lightBtnTitle {
color: white;
font-size: 18px;
}
.lightBtnSubtitle {
color: rgba(255, 255, 255, 0.5);
font-size: 14px;
}
import React, {useState} from 'react';
import clsx from 'clsx';
// import { View } from '@ray-js/ray';
import { DpBooleanAction, DpCommonAction } from '@tuya-miniapp/sdm';
import { useSdmProps } from '@ray-js/sdm-react';
import {devices} from '@/devices'
import styles from './index.module.less';
import { Image, View } from '@ray-js/components'
import iconClose from '../../../public/icon-close.png'
import iconLightWhite from '../../../public/icon-light-white.png'
import iconSun from '../../../public/icon-sun.png'
export interface Props {
isShow: boolean;
setModal: (boolean) => void;
}
export const LightPanel = React.memo<Props>(props => {
const brightRange = [10, 1000]
const cctRange = [0, 1000]
const brightCode = 'bright_value'
const temperatureCode = 'temp_value'
const switchCode = 'switch_led'
let { isShow, setModal} = props;
const brightVal = useSdmProps(dpState => {
const val = dpState[brightCode]
const percent = getValueInRange(val || 10, brightRange).percent
return percent
});
const temperatureVal = useSdmProps(dpState => {
const val = dpState[temperatureCode]
const percent = getValueInRange(val || 0, cctRange).percent
return percent
});
const switchVal = useSdmProps(dpState => dpState[switchCode]);
const device = devices.fan
const actions = device.model.actions
const switchAction = actions[switchCode] as DpBooleanAction
const brightAction = actions[brightCode] as DpCommonAction<number>
const temperatureAction = actions[temperatureCode] as DpCommonAction<number>
const [point, setPoint] = useState({pageX: getOrignPointX(), pageY: 234})
const [selectColor, setColor] = useState(pointToRGB(point.pageX))
function getOrignPointX() {
const percent = getValueInRange(temperatureVal || 10, cctRange).percent
return 28 + 319 * Number((percent / 100).toFixed())
}
//0-value是值 1-value是百分比 左边最小值是0,右边最大值range[1],起始位置rang[0]
function getValueInRange(value, range, type = 0) {
const percent = type == 0 ? (value / range[1]) : (value / 100)
return {
value: type == 0 ? value : (percent * range[1]).toFixed(),
percent: type == 0 ? (percent * 100).toFixed() : value
}
}
function touchStart(e) {
console.log(e, 'start touch');
handlePoint(e)
}
function handleTouch(e) {
// console.log(e, 'handle touch');
// const point = e.changedTouches.length && e.changedTouches[0]
// console.log(point, 'pppppppoint');
// handlePoint(e)
}
function touchEnd(e) {
console.log(e, 'end touch');
handlePoint(e)
}
function handlePoint(e) {
const {pageX, pageY} = e.changedTouches.length && e.changedTouches[0]
let x = pageX
let y = pageY
const xRange = [28, 347]
if (pageX < xRange[0]) {
x = xRange[0]
}
if (pageX > xRange[1]) {
x = xRange[1]
}
if (pageY < 197) {
y = 197
}
if (pageY > 320) {
y =320
}
setPoint({pageX: x, pageY: y})
const percent = (x - xRange[0]) / (xRange[1] - xRange[0])
const value = Number((cctRange[1] * percent).toFixed())
setColor(pointToRGB(x))
temperatureAction.set(value)
}
function pointToRGB(pageX) {
const half = (347 - 28) / 2
const middle = 28 + half
const leftColor = {h: 40, s:100, l:68}
const rightColor = {h:202,s:96, l:90}
let newL = leftColor.l
let color = leftColor
if (pageX < middle) {
newL = 68 + (pageX - 28) * 32 / 161
leftColor.l = newL
color = leftColor
} else {
newL = 100 - (pageX - middle) * 10 / 161
rightColor.l = newL
color = rightColor
}
return HSLToRGB(color)
}
function HSLToRGB({h, s, l}) {
s /= 100;
l /= 100;
const k = n => (n + h / 30) % 12;
const a = s * Math.min(l, 1 - l);
const f = n =>
l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
const color = `rgb(${255 * f(0)}, ${255 * f(8)}, ${255 * f(4)})`
console.log(color)
return color
};
const handleLightOn = () => {
switchAction.toggle()
}
function progressStart(e) {
console.log(e, 'progressStart');
handleProgress(e)
}
function progressMove(e) {
console.log(e, 'progressMove');
// handleProgress(e)
}
function progressEnd(e) {
console.log(e, 'progressEnd');
handleProgress(e)
}
function handleProgress(e) {
let {pageX, pageY} = e.changedTouches.length && e.changedTouches[0]
const xRange = [20,335]
let differ = pageX - xRange[0]
if (differ < 0) {
differ = 0
} else if (differ > xRange[1]) {
differ = xRange[1]
}
const percent = differ / (xRange[1] - xRange[0]);
const value = Number((brightRange[1] * percent).toFixed())
brightAction.set(value)
}
return (
<View className={styles.modalback} style={{background:'rgba(0, 0, 0, 0.1)',backdropFilter:'blur(35px)', visibility: isShow ? 'visible':'hidden' }}>
<View className={styles.lightModal}>
<View className={styles.lightModalTop}>
<View>Light
</View>
<Image className={styles.lightModalClose} src={iconClose} onClick={() => {
setModal(false)
}}></Image>
</View>
<View
className={styles.lightMiddle}
onTouchStart={touchStart}
onTouchMove={handleTouch}
onTouchEnd={touchEnd}
>
</View>
<View className={styles.progressBg} onTouchStart={progressStart}
onTouchMove={progressMove}
onTouchEnd={progressEnd}>
<Image className={styles.progressSun} src={iconSun}></Image>
<View className={styles.progressTitle}>{brightVal}%</View>
<View className={styles.progressBar} style={{width: brightVal + '%'}}></View>
</View>
<View className={styles.lightBtn} style={{backgroundColor: switchVal ? '#6395F6':'rgba(0,0,0,0.5)'}} onClick={handleLightOn}>
<Image className={styles.lightBtnIcon} src={iconLightWhite}></Image>
<View className={styles.lightBtnTitle}>{switchVal ? 'ON':'OFF'}</View>
<View className={styles.lightBtnSubtitle}>{switchVal ? '/OFF':'/ON'}</View>
</View>
</View>
<View className={styles.moveCircle} style={{top: point.pageY - 14 + 'px', left: point.pageX - 14 + 'px', backgroundColor: selectColor}}></View>
</View>
)
})
\ No newline at end of file
export const ProductName = 'fan';
import { SmartDeviceModel } from '@tuya-miniapp/sdm';
// import { ProductName } from '@/constants';
type SmartDeviceSchema = typeof import('@/devices/schema').fanSchema;
// type SmartDevices = {
// [ProductName]?: import('@tuya-miniapp/sdm').SmartDeviceModel<SmartDeviceSchema>;
// };
export const devices = {
fan: new SmartDeviceModel<SmartDeviceSchema>(),
};
Object.keys(devices).forEach((k: keyof typeof devices) => {
devices[k].init();
});
export const defaultSchema = [
export const fanSchema = [
{
"attr": 1667,
"attr": 0,
"canTrigger": true,
"code": "switch_led",
"defaultRecommend": true,
"editPermission": true,
"code": "switch",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-dp_power",
"id": 20,
"id": 1,
"mode": "rw",
"name": "开关",
"name": "开关",
"property": {
"type": "bool"
},
"type": "obj"
},
{
"attr": 1664,
"attr": 0,
"canTrigger": true,
"code": "work_mode",
"defaultRecommend": true,
"editPermission": true,
"code": "mode",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-dp_mode",
"id": 21,
"id": 2,
"mode": "rw",
"name": "模式",
"name": "模式",
"property": {
"range": [
"white",
"colour",
"scene",
"music"
"nature",
"sleep",
"fresh",
"smart",
"strong"
],
"type": "enum"
},
"type": "obj"
},
{
"attr": 1664,
"attr": 0,
"canTrigger": true,
"code": "bright_value",
"defaultRecommend": true,
"editPermission": true,
"code": "fan_speed",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-liangdu1",
"id": 22,
"id": 3,
"mode": "rw",
"name": "亮度值",
"name": "风速",
"property": {
"min": 10,
"max": 1000,
"min": 1,
"max": 100,
"scale": 0,
"step": 1,
"type": "value"
......@@ -61,247 +59,245 @@ export const defaultSchema = [
"type": "obj"
},
{
"attr": 1664,
"attr": 0,
"canTrigger": true,
"code": "temp_value",
"defaultRecommend": true,
"editPermission": true,
"code": "switch_vertical",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-dp_half",
"id": 23,
"id": 4,
"mode": "rw",
"name": "冷暖值",
"name": "上下摆风开关",
"property": {
"min": 0,
"max": 1000,
"scale": 0,
"step": 1,
"type": "value"
"type": "bool"
},
"type": "obj"
},
{
"attr": 1664,
"attr": 0,
"canTrigger": true,
"code": "colour_data",
"defaultRecommend": true,
"editPermission": true,
"code": "switch_horizontal",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-yanse",
"id": 24,
"id": 5,
"mode": "rw",
"name": "彩光",
"name": "左右摆风开关",
"property": {
"type": "string",
"maxlen": 255
"type": "bool"
},
"type": "obj"
},
{
"attr": 1664,
"attr": 0,
"canTrigger": true,
"code": "scene_data",
"defaultRecommend": true,
"editPermission": true,
"code": "fan_vertical",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-shoucang",
"id": 25,
"id": 6,
"mode": "rw",
"name": "场景",
"name": "上下摆风",
"property": {
"type": "string",
"maxlen": 255
"range": [
"30",
"60",
"90"
],
"type": "enum"
},
"type": "obj"
},
{
"attr": 1664,
"attr": 0,
"canTrigger": true,
"code": "countdown",
"defaultRecommend": true,
"editPermission": true,
"code": "fan_horizontal",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-a_nav_timer",
"id": 26,
"id": 7,
"mode": "rw",
"name": "灯倒计时",
"name": "左右摆风",
"property": {
"unit": "s",
"min": 0,
"max": 86400,
"scale": 0,
"step": 1,
"type": "value"
"range": [
"30",
"60",
"90"
],
"type": "enum"
},
"type": "obj"
},
{
"attr": 128,
"attr": 0,
"canTrigger": true,
"code": "music_data",
"code": "fan_direction",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-deng",
"id": 27,
"mode": "wr",
"name": "音乐灯",
"id": 8,
"mode": "rw",
"name": "风向",
"property": {
"type": "string",
"maxlen": 255
"range": [
"forward",
"reverse"
],
"type": "enum"
},
"type": "obj"
},
{
"attr": 1664,
"attr": 0,
"canTrigger": true,
"code": "control_data",
"defaultRecommend": true,
"editPermission": true,
"code": "anion",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-dp_box2",
"id": 28,
"mode": "wr",
"name": "调节",
"id": 9,
"mode": "rw",
"name": "负离子",
"property": {
"type": "string",
"maxlen": 255
"type": "bool"
},
"type": "obj"
},
{
"attr": 128,
"attr": 0,
"canTrigger": true,
"code": "power_memory",
"code": "humidifier",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-Trigger",
"id": 33,
"id": 10,
"mode": "rw",
"name": "断电记忆",
"type": "raw"
"name": "加湿",
"property": {
"type": "bool"
},
"type": "obj"
},
{
"attr": 128,
"attr": 0,
"canTrigger": true,
"code": "do_not_disturb",
"code": "oxygen",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-dp_mode",
"id": 34,
"id": 11,
"mode": "rw",
"name": "勿扰模式",
"name": "氧吧",
"property": {
"type": "bool"
},
"type": "obj"
},
{
"attr": 128,
"attr": 0,
"canTrigger": true,
"code": "switch_gradient",
"code": "fan_cool",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-dp_mode",
"id": 35,
"id": 12,
"mode": "rw",
"name": "开关渐变",
"type": "raw"
"name": "冷风",
"property": {
"type": "bool"
},
"type": "obj"
},
{
"attr": 128,
"attr": 0,
"canTrigger": true,
"code": "mix_light_scene",
"code": "fan_beep",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-dp_mode",
"id": 36,
"id": 13,
"mode": "rw",
"name": "混光场景",
"type": "raw"
"name": "声音",
"property": {
"type": "bool"
},
"type": "obj"
},
{
"attr": 640,
"attr": 0,
"canTrigger": true,
"code": "mix_rgbcw",
"defaultRecommend": true,
"code": "child_lock",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-deng",
"id": 51,
"id": 14,
"mode": "rw",
"name": "混光",
"type": "raw"
"name": "童锁",
"property": {
"type": "bool"
},
"type": "obj"
},
{
"attr": 1664,
"attr": 16,
"canTrigger": true,
"code": "fan_switch",
"defaultRecommend": true,
"editPermission": true,
"code": "light",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-dp_power2",
"id": 60,
"id": 15,
"mode": "rw",
"name": "风扇开关",
"name": "灯光",
"property": {
"type": "bool"
},
"type": "obj"
},
{
"attr": 1664,
"attr": 0,
"canTrigger": true,
"code": "fan_mode",
"defaultRecommend": true,
"editPermission": true,
"code": "bright_value",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-a_mode_fan",
"id": 61,
"id": 16,
"mode": "rw",
"name": "风模式",
"name": "灯光亮度",
"property": {
"range": [
"fresh",
"nature"
],
"type": "enum"
"min": 10,
"max": 1000,
"scale": 0,
"step": 1,
"type": "value"
},
"type": "obj"
},
{
"attr": 1664,
"attr": 0,
"canTrigger": true,
"code": "fan_speed",
"defaultRecommend": true,
"editPermission": true,
"code": "temp_value",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-FanSpeed",
"id": 62,
"id": 17,
"mode": "rw",
"name": "风速",
"name": "灯光色温",
"property": {
"unit": "转速",
"min": 1,
"max": 200,
"min": 0,
"max": 1000,
"scale": 0,
"step": 1,
"type": "value"
......@@ -309,42 +305,41 @@ export const defaultSchema = [
"type": "obj"
},
{
"attr": 1664,
"attr": 0,
"canTrigger": true,
"code": "fan_direction",
"defaultRecommend": true,
"editPermission": true,
"code": "work_mode",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-dp_mode",
"id": 63,
"id": 19,
"mode": "rw",
"name": "风向",
"name": "灯光模式",
"property": {
"range": [
"forward",
"reverse"
"white",
"colour",
"colourful"
],
"type": "enum"
},
"type": "obj"
},
{
"attr": 1664,
"attr": 0,
"canTrigger": true,
"code": "fan_countdown_left",
"defaultRecommend": true,
"editPermission": true,
"code": "temp_set",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-dp_time3",
"id": 64,
"id": 20,
"mode": "rw",
"name": "风扇倒计时",
"name": "温度设置",
"property": {
"unit": "min",
"unit": "",
"min": 0,
"max": 540,
"max": 50,
"scale": 0,
"step": 1,
"type": "value"
......@@ -352,32 +347,81 @@ export const defaultSchema = [
"type": "obj"
},
{
"attr": 1152,
"attr": 0,
"canTrigger": true,
"code": "fan_beep",
"code": "temp_current",
"defaultRecommend": false,
"editPermission": true,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-dp_voice",
"id": 66,
"id": 21,
"mode": "ro",
"name": "当前温度",
"property": {
"unit": "℃",
"min": 0,
"max": 50,
"scale": 0,
"step": 1,
"type": "value"
},
"type": "obj"
},
{
"attr": 0,
"canTrigger": true,
"code": "countdown_set",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"id": 22,
"mode": "rw",
"name": "蜂鸣器",
"name": "倒计时",
"property": {
"type": "bool"
"range": [
"cancel",
"1h",
"2h",
"3h",
"4h",
"5h",
"6h"
],
"type": "enum"
},
"type": "obj"
},
{
"attr": 0,
"canTrigger": true,
"code": "countdown_left",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"id": 23,
"mode": "ro",
"name": "倒计时剩余时间",
"property": {
"unit": "min",
"min": 0,
"max": 360,
"scale": 0,
"step": 1,
"type": "value"
},
"type": "obj"
},
{
"attr": 1152,
"attr": 0,
"canTrigger": true,
"code": "fault",
"defaultRecommend": false,
"editPermission": true,
"editPermission": false,
"executable": true,
"extContent": "",
"iconname": "icon-baojing",
"id": 67,
"id": 24,
"mode": "ro",
"name": "故障告警",
"property": {
......@@ -388,5 +432,25 @@ export const defaultSchema = [
"maxlen": 1
},
"type": "obj"
},
{
"attr": 0,
"canTrigger": true,
"code": "temp_unit_convert",
"defaultRecommend": false,
"editPermission": false,
"executable": true,
"extContent": "",
"id": 28,
"mode": "rw",
"name": "温标切换",
"property": {
"range": [
"c",
"f"
],
"type": "enum"
},
"type": "obj"
}
]
\ No newline at end of file
import { GlobalConfig } from '@ray-js/types';
export const wechat = {
window: {
backgroundColor: '#E3EEF6',
navigationBarTitleText: 'Fan',
navigationBarBackgroundColor: '#E3EEF6',
navigationBarTextStyle: 'black',
},
}
// export const wechat = {
// window: {
// backgroundColor: '#E3EEF6',
// navigationBarTitleText: 'Fan',
// navigationBarBackgroundColor: '#E3EEF6',
// navigationBarTextStyle: 'black',
// },
// }
export const web = {
window: {
backgroundColor: '#E3EEF6',
navigationBarTitleText: 'Fan',
},
};
// export const web = {
// window: {
// backgroundColor: '#E3EEF6',
// navigationBarTitleText: 'Fan',
// },
// };
export const tuya = {
window: {
......
......@@ -172,119 +172,7 @@
height: 64px;
}
.lightModal {
display: flex;
flex-direction: column;
// margin: auto;
width: 340px;
height: 424px;
background-color: white;
border-radius: 24px;
// position: absolute;
// top: calc(50vh - 175px);
margin-top: 90px;
padding: 20px 0 40px;
color: #000000;
z-index: 9999;
}
.lightModalTop {
display: flex;
align-items: center;
padding: 0 20px;
width: 100%;
justify-content: space-between;
font-size: 16px;
margin-bottom: 40px;
}
.lightModalClose {
width: 24px;
height: 24px;
}
.lightMiddle {
// width: 100%;
height: 155px;
border-radius: 16px 16px 0 0;
background: linear-gradient(-90deg, #cdecfe 0%, #ffffff 45.46%, #ffffff 53.61%, #ffca5c 100%);
position: relative;
margin: 0 3px;
}
.modalback {
position: fixed;
top: 0;
left: 0;
right: 0;
bottom: 0;
z-index: 99;
display: flex;
// align-items: center;
justify-content: center;
}
.moveCircle {
width: 28px;
height: 28px;
border: 3px solid #ffffff;
border-radius: 14px;
position: absolute;
background-color: #ffca5c;
z-index: 10001;
}
.progressBg {
// width: 100%;
height: 40px;
border-radius: 0 0 16px 16px;
background-color: #e5e5e5;
display: flex;
align-items: center;
padding-left: 16px;
font-size: 16px;
position: relative;
overflow: hidden;
margin: 0 3px;
}
.progressSun {
width: 21px;
height: 21px;
margin-right: 9px;
z-index: 9999;
}
.progressTitle {
z-index: 9999;
}
.progressBar {
background-color: white;
position: absolute;
left: 1px;
top: 1px;
bottom: 1px;
z-index: 2;
}
.lightBtn {
width: 310px;
height: 56px;
border-radius: 24px;
align-items: center;
justify-content: center;
display: flex;
background-color: rgba(0, 0, 0, 0.5);
align-self: center;
margin-top: 48px;
}
.lightBtnIcon {
width: 18px;
height: 26px;
margin-right: 14px;
}
.lightBtnTitle {
color: white;
font-size: 18px;
}
.lightBtnSubtitle {
color: rgba(255, 255, 255, 0.5);
font-size: 14px;
}
.swiperItem {
display: flex;
......@@ -301,8 +189,6 @@
padding-left: 20px;
}
.verticalBg {
}
.verticalItem {
display: flex;
......
import { Button, ScrollView, Text, View, Swiper, SwiperItem} from '@ray-js/components';
import {
getSystemInfo,
onNetworkStatusChange,
offNetworkStatusChange,
onBluetoothAdapterStateChange,
offBluetoothAdapterStateChange,
showToast,
showLoading,
hideLoading,
getAppInfo,
bluetoothIsPowerOn,
publishDps,
getDeviceInfo,
openDeviceDetailPage,
openTimerPage,
} from '@ray-js/api';
import { hooks } from '@ray-js/panel-sdk';
import { router, usePageEvent } from 'ray';
import { Text, View, Swiper, SwiperItem} from '@ray-js/components';
// import {
// getSystemInfo,
// onNetworkStatusChange,
// offNetworkStatusChange,
// onBluetoothAdapterStateChange,
// offBluetoothAdapterStateChange,
// showToast,
// showLoading,
// hideLoading,
// getAppInfo,
// bluetoothIsPowerOn,
// publishDps,
// getDeviceInfo,
// openDeviceDetailPage,
// openTimerPage,
// } from '@ray-js/api';
// import { hooks } from '@ray-js/panel-sdk';
import { router, usePageEvent, setNavigationBarTitle } from '@ray-js/ray';
import React from 'react';
import { useSelector } from '@/redux';
import styles from './index.module.less';
......@@ -30,9 +30,7 @@ import iconLight from '../../../public/icon-light.png'
import iconVertical from '../../../public/icon-vertical.png'
import iconOpenOff from '../../../public/icon-open-off.png'
import middleware from '../../../public/icon-middleware.png'
import iconClose from '../../../public/icon-close.png'
import iconLightWhite from '../../../public/icon-light-white.png'
import iconSun from '../../../public/icon-sun.png'
import nature from '../../../public/icon-nature.png'
import natureOn from '../../../public/icon-nature-on.png'
import moon from '../../../public/icon-moon.png'
......@@ -45,18 +43,40 @@ import hand from '../../../public/icon-hand.png'
import handOn from '../../../public/icon-hand-on.png'
import mode from '../../../public/icon-mode.png'
import modeOn from '../../../public/icon-mode-on.png'
import horizontalOff from '../../../public/icon-horizontal-off.png'
import horizontalOn from '../../../public/icon-horizontal-on.png'
import verticalOn from '../../../public/icon-vertical-on.png'
import verticalOff from '../../../public/icon-vertical-off.png'
import {useState, useEffect} from 'react'
import { LightPanel,FanVertical } from '@/components';
import { useSdmProps, useSdmDevice} from '@ray-js/sdm-react';
import {devices} from '@/devices'
import { DpBooleanAction, DpCommonAction} from '@tuya-miniapp/sdm';
const { useDevInfo, useDpState } = hooks;
export function Home() {
const devInfo = useDevInfo();
const devState = useDpState()
const deviceName = useSdmDevice(d => d.devInfo.name)
useEffect(() => {
setNavigationBarTitle({ title: deviceName });
}, [deviceName])
const fanSwitchCode = 'switch'
const fanSpeedCode = 'fan_speed'
const fanModeCode = 'mode'
const currentTempCode = 'temp_current'
const isOpen = useSdmProps((props) => props[fanSwitchCode])
const spinSpeed = useSdmProps((props) => Number(props[fanSpeedCode]))
const fanModeVal = useSdmProps((props) => props[fanModeCode])
const currentTempVal = useSdmProps((props) => props[currentTempCode])
const device = devices.fan
const actions = device.model.actions
const switchAction = actions[fanSwitchCode] as DpBooleanAction
const speedAction = actions[fanSpeedCode] as DpCommonAction<number>
const fanModeAction = actions[fanModeCode] as DpCommonAction<string>
const menu = [
{
title:'Switch',
......@@ -82,119 +102,67 @@ export function Home() {
title:'Nature',
icon:natureOn,
offIcon: nature,
id: 0
id: 0,
mode:'nature'
}, {
title:'Sleep',
icon:moonOn,
offIcon: moon,
id: 1
id: 1,
mode:'sleep'
}, {
title:'Fresh',
icon:freshOn,
offIcon: fresh,
id: 2
id: 2,
mode: 'fresh',
}, {
title:'Smart',
icon:smartOn,
offIcon: smart,
id: 3
id: 3,
mode:'smart'
}]
const secondMenu = [
// {
// title:'Nature',
// icon:handOn,
// offIcon: hand,
// id: 4
// },
{
title:'Nature',
icon:handOn,
offIcon: hand,
id: 4
}, {
title:'Mode',
title:'Strong',
icon:modeOn,
offIcon: mode,
id: 5
id: 4,
mode:'strong'
}
]
const verticalMenu = [
{
title:'Vertical',
icon:verticalOn,
offIcon: verticalOff,
id: 7,
numId:[71, 72, 73]
}, {
title:'Horizontal',
icon:horizontalOn,
offIcon: horizontalOff,
id:8,
numId:[81, 82, 83]
}
]
const brightRange = [10, 1000]
const cctRange = [0, 1000]
const [currentTemp, setTemp] = useState(devState[0]['temp_current'] || 30)
const [spinSpeed, setSpeed] = useState(devState[0]['fan_speed'] || 1)
const [isOpen, setOpen] = useState(devState[0]['fan_switch'] || false)
const [menuIndex, setMenuIndex] = useState(null)
const [preTime, setPreTime] = useState(null)
// const [preTime, setPreTime] = useState(null)
const [isShowModal, setModal] = useState(false)
const [point, setPoint] = useState({pageX: getOrignPointX(), pageY: 234})
const [selectColor, setColor] = useState(pointToRGB(point.pageX))
//亮度
const [bright, setBright] = useState(getValueInRange(devState[0]['bright_value'] || 10, brightRange).percent)
const [isLightOn, setLightOn] = useState(devState[0]['switch_led'] || false)
const [secondIndex, setSecondIndex] = useState(getFanMode())
const [verticalId, setVerticalId] = useState(getOrignFanVertical())
const [cctPercent, setCctPercent] = useState(getValueInRange(devState[0]['temp_value'] || 0, cctRange).percent)
useEffect(() => {
console.log('useEffffffffff', isOpen);
uploadDps()
}, [isOpen, spinSpeed, isLightOn, bright, cctPercent, secondIndex])
function getFanMode() {
const preMode = devState[0]['fan_mode']
let selected = null
for (let index = 0; index < firstMenu.length; index++) {
const item = firstMenu[index];
const title = item.title.toLowerCase()
if (title == preMode) {
selected = item.id
}
}
return selected
}
function getOrignPointX() {
const percent = getValueInRange(devState[0]['temp_value'] || 10, cctRange).percent
return 28 + 319 * Number((percent / 100).toFixed())
}
//0-value 1-percent
function getValueInRange(value, range, type = 0) {
const diff = range[1] - range[0]
const percent = type == 0 ? (value / diff) : (value / 100)
return {
value: type == 0 ? value : (range[0] + percent * diff).toFixed(),
percent: (percent * 100).toFixed()
}
}
function spinDuration() {
return 2 - ((2 - 0.2) / 100) * spinSpeed + 's'
if (spinSpeed == 0) {
return '0s'
} else {
return 2 - ((2 - 0.2) / 100) * spinSpeed + 's'
}
}
function clickMenu(e) {
console.log(e, preTime);
// if ((e.timeStamp > preTime + 20) || !preTime) {
setPreTime(e.timeStamp)
const index = e.currentTarget.id
if (index == 0) {
setOpen(!isOpen)
switchAction.toggle()
setMenuIndex(null)
}else if (isOpen) {
}
else if (isOpen) {
if (index == 2) {
setMenuIndex(null)
setModal(true)
......@@ -205,236 +173,32 @@ export function Home() {
setMenuIndex(index)
}
}
// }
}
}
function touchStart(e) {
console.log(e, 'start touch');
handlePoint(e)
}
function handleTouch(e) {
// console.log(e, 'handle touch');
// const point = e.changedTouches.length && e.changedTouches[0]
// console.log(point, 'pppppppoint');
// handlePoint(e)
}
function touchEnd(e) {
console.log(e, 'end touch');
handlePoint(e)
}
function handlePoint(e) {
const {pageX, pageY} = e.changedTouches.length && e.changedTouches[0]
let x = pageX
let y = pageY
if (pageX < 28) {
x = 28
}
if (pageX > 347) {
x = 347
}
if (pageY < 197) {
y = 197
}
if (pageY > 320) {
y =320
}
setPoint({pageX: x, pageY: y})
const percent = ((x - 28) / 319 * 100).toFixed()
setCctPercent(percent)
setColor(pointToRGB(x))
}
function pointToRGB(pageX) {
const half = (347 - 28) / 2
const middle = 28 + half
const leftColor = {h: 40, s:100, l:68}
const rightColor = {h:202,s:96, l:90}
let newL = leftColor.l
let color = leftColor
if (pageX < middle) {
newL = 68 + (pageX - 28) * 32 / 161
leftColor.l = newL
color = leftColor
} else {
newL = 100 - (pageX - middle) * 10 / 161
rightColor.l = newL
color = rightColor
}
// setLight(Number(newL).toFixed(0))
console.log(newL, color, leftColor, rightColor);
return HSLToRGB(color)
}
function HSLToRGB({h, s, l}) {
s /= 100;
l /= 100;
const k = n => (n + h / 30) % 12;
const a = s * Math.min(l, 1 - l);
const f = n =>
l - a * Math.max(-1, Math.min(k(n) - 3, Math.min(9 - k(n), 1)));
const color = `rgb(${255 * f(0)}, ${255 * f(8)}, ${255 * f(4)})`
console.log(color)
return color
};
const handleLightOn = () => {
setLightOn(!isLightOn)
}
function progressStart(e) {
console.log(e, 'progressStart');
handleProgress(e)
}
function progressMove(e) {
console.log(e, 'progressMove');
handleProgress(e)
}
function progressEnd(e) {
console.log(e, 'progressEnd');
handleProgress(e)
}
function handleProgress(e) {
const {pageX, pageY} = e.changedTouches.length && e.changedTouches[0]
const minX = 20
const maxX = 355
let differ = pageX - minX
if (differ < 0) {
differ = 0
} else if (differ > 335) {
differ = 335
}
const percent = (differ / 335 * 100).toFixed()
setBright(percent)
}
function getOrignFanVertical() {
const fan_vertical = devState[0]['fan_vertical']
const fan_horizontal = devState[0]['fan_horizontal']
const num_vertical = fan_vertical ? parseInt(fan_vertical / 30) : null
const num_horizontal = fan_horizontal ? parseInt(fan_horizontal / 30) :null
if (num_vertical) {
return 70 + num_vertical
}
if (num_horizontal) {
return 80 + num_horizontal
}
return null
}
//dpId 每个设备不一样
function getSelectFanVertical() {
if (verticalId) {
const value = (verticalId % 70) * 30
if (verticalId < 80) {
return {
'6' : value
}
}else {
return {
'7' : value
}
}
}
return {}
}
function uploadDps(params = {}) {
const brightValue = getValueInRange(bright, brightRange, 1).value
const cctValue = getValueInRange(cctPercent, cctRange, 1).value
const mode = firstMenu.filter(item => item.id == secondIndex)
const selectMode = mode.length > 0 ? {'61': mode[0].title.toLowerCase()} : {'61': null}
console.log(brightValue, 'brightValue');
console.log(cctValue, 'cctValue');
publishDps({
deviceId: devInfo.devId,
// dps: { '60': isOpen, '61':selectMode, '62': spinSpeed, '20':isLightOn, '22': brightValue, '23':cctValue}, // {'dpid': dpValue, '2': false}
dps: { '60': isOpen, ...selectMode, '62': spinSpeed, '20':isLightOn},
mode: 2,
pipelines: [],
options: {}, // 0,静音; 1,震动;2,声音; 3,震动声音
success: () => console.log('success'),
fail: d => {
console.log('-----返回结果错误?', d);
},
});
}
function handleSubmenu(id) {
if (id == secondIndex) {
setSecondIndex(null)
} else {
setSecondIndex(id)
function handleSubmenu(mode) {
if (mode !== fanModeVal) {
fanModeAction.set(mode)
}
}
function submenuItem(index, arr = firstMenu, clickFun = handleSubmenu, currentIndex = secondIndex) {
// const arr = page == 0 ? firstMenu:secondMenu
const {title, id, icon, offIcon} = arr[index]
function submenuItem(index, arr = firstMenu, clickFun = handleSubmenu, currentIndex = fanModeVal) {
const {title, mode, icon, offIcon} = arr[index]
return (
<View className={styles.button}>
<Image className={styles.menuImage} src={id == currentIndex ? icon:offIcon} onClick={() => {clickFun(id)}}/>
<Image className={styles.menuImage} src={mode == currentIndex ? icon:offIcon} onClick={() => {clickFun(mode)}}/>
<Text className={styles.bTitle}>{title}</Text>
</View>
)
}
function handleVerticalMenu(id) {
const tensPre = parseInt(verticalId/10)
// const tensCur = id / 10
if (tensPre == id) {
setVerticalId(null)
} else {
setVerticalId(id * 10 + 2)
}
}
function verticalItem(index) {
const item = verticalMenu[index]
const textColor = (subIndex) => {
return {color: verticalId == item.numId[subIndex] ? '#000000':'rgba(0,0,0,0.4)',
width:'33.3%',
textAlign:'center',
lineHeight:'64px',
fontWeight:'500'
}}
const clickNum = (index) => {
const id = item.numId[index]
if (id == verticalId) {
setVerticalId(null)
} else {
setVerticalId(id)
}
}
return (
<View className={styles.verticalItem}>
{submenuItem(index, verticalMenu, handleVerticalMenu, parseInt(verticalId / 10))}
<View className={styles.verticalNumBg}>
<View style={textColor(0)} onClick={() => {clickNum(0)}}>30</View>
<View style={textColor(1)} onClick={() => {clickNum(1)}}>60</View>
<View style={textColor(2)} onClick={() => {clickNum(2)}}>90</View>
</View>
</View>
)
}
return (
<View className={styles.page}>
<View className={styles.header}>
<View className={styles.alignCenter}>
<Image className={styles.icon} src={iconTempr} />
<View className={styles.title}>{currentTemp}°C</View>
<View className={styles.title}>{currentTempVal}°C</View>
</View>
{/* <View className={styles.timer}>Countdown to open 03:00</View> */}
</View>
......@@ -450,12 +214,11 @@ export function Home() {
min={0}
max={100}
value={spinSpeed}
step={5}
step={1}
disabled={!isOpen}
onChange={(e) => {
console.log('SliderChange', e)
setSpeed(e.value)
// publishDps()
speedAction.set(e.value)
}}
/>
<View className={styles.fantBottom}>
......@@ -491,30 +254,22 @@ export function Home() {
}
</View>
</SwiperItem>
{/* <SwiperItem>
<SwiperItem>
<View className={styles.swiperItemNext}>
{
submenuItem(0, secondMenu)
}
{
submenuItem(1, secondMenu)
}
</View>
</SwiperItem> */}
</SwiperItem>
</Swiper>
</View>
: menuIndex == 3 ? <View className={styles.modalBg} style={{height: '213px', display: 'flex', flexDirection:'column', padding:'16px 16px 0', gap:'12px'}}>
{
verticalItem(0)
}
{
verticalItem(1)
}
<FanVertical></FanVertical>
</View>
: null
}
<Image className={styles.middleware} src={middleware} style={{visibility: menuIndex == index ? 'visible':'hidden'}} />
<Image src={index > 0 ? icon: isOpen ? icon:offIcon} className={styles.menuImage} id={index} style={{opacity: isOpen ? 1: index > 0 ? 0.4:1 }} onClick={
<Image src={index > 0 ? icon: isOpen ? icon:offIcon} className={styles.menuImage} id={String(index) } style={{opacity: isOpen ? 1: index > 0 ? 0.4:1 }} onClick={
clickMenu
}></Image>
<Text className={styles.bTitle}>{title}</Text>
......@@ -523,37 +278,10 @@ export function Home() {
})
}
</View>
<View className={styles.modalback} style={{background:'rgba(0, 0, 0, 0.1)',backdropFilter:'blur(35px)', visibility: isShowModal ? 'visible':'hidden' }}>
<View className={styles.lightModal}>
<View className={styles.lightModalTop}>
<View>Light
</View>
<Image className={styles.lightModalClose} src={iconClose} onClick={() => {
setModal(false)
}}></Image>
</View>
<View
className={styles.lightMiddle}
onTouchStart={touchStart}
onTouchMove={handleTouch}
onTouchEnd={touchEnd}
>
</View>
<View className={styles.progressBg} onTouchStart={progressStart}
onTouchMove={progressMove}
onTouchEnd={progressEnd}>
<Image className={styles.progressSun} src={iconSun}></Image>
<View className={styles.progressTitle}>{bright}%</View>
<View className={styles.progressBar} style={{width: bright + '%'}}></View>
</View>
<View className={styles.lightBtn} style={{backgroundColor: isLightOn ? '#6395F6':'rgba(0,0,0,0.5)'}} onClick={handleLightOn}>
<Image className={styles.lightBtnIcon} src={iconLightWhite}></Image>
<View className={styles.lightBtnTitle}>{isLightOn ? 'ON':'OFF'}</View>
<View className={styles.lightBtnSubtitle}>{isLightOn ? '/OFF':'/ON'}</View>
</View>
</View>
<View className={styles.moveCircle} style={{top: point.pageY - 14 + 'px', left: point.pageX - 14 + 'px', backgroundColor: selectColor}}></View>
</View>
<LightPanel
isShow={isShowModal}
setModal={setModal}
></LightPanel>
</View>
)
}
......
import { Routes, TabBar } from '@ray-js/types';
import { Routes} from '@ray-js/types';
export const routes: Routes = [
{
......@@ -6,16 +6,15 @@ export const routes: Routes = [
path: '/pages/home/index',
name: 'Home',
},
{
route: '/common/page4/index',
path: '/pages/common/page4/index',
name: 'Page4',
},
{
route: '/common/page6/index',
path: '/pages/common/page6/index',
name: 'Page6',
},
// {
// route: '/common/page4/index',
// path: '/pages/common/page4/index',
// name: 'Page4',
// },
// {
// route: '/common/page6/index',
// path: '/pages/common/page6/index',
// name: 'Page6',
// },
];
export const tabBar = {};
......@@ -3,11 +3,8 @@
"compilerOptions": {
"target": "ES2015",
"module": "CommonJS",
"lib": [
"ESNext",
"DOM"
],
"declaration": false,
"lib": ["ESNext", "DOM"],
"declaration": true,
"declarationMap": false,
"emitDeclarationOnly": false,
"moduleResolution": "node",
......@@ -17,28 +14,13 @@
"resolveJsonModule": true,
"noEmitOnError": false,
"jsx": "react",
"baseUrl": "./",
"paths": {
"ray": [
"./.ray"
],
"@/*": [
"./src/*"
]
"ray": ["./.ray"],
"@/*": ["./src/*"],
"@/components/*": ["./src/components/*"]
},
"typeRoots": [
"./node_modules/@types",
"./typings",
"./node_modules/@tuya-miniapp"
],
"types": []
},
"include": [
"src/**/*.*",
"ray/**/*.*",
"typings"
],
"exclude": [
"node_modules",
"dist"
]
}
\ No newline at end of file
"include": ["src/**/*.*", ".ray/**/*.*", "typings"],
"exclude": ["node_modules", "dist", "public"]
}
import { ProductName } from '@/constants';
type SmartDeviceSchema = typeof import('@/devices/schema').fanSchema;
type SmartDevices = {
[ProductName]?: import('@tuya-miniapp/sdm').SmartDeviceModel<SmartDeviceSchema>;
};
declare module '@ray-js/sdm-react' {
// export const SdmProvider: React.FC<{
// value: SmartDeviceModel<SmartDeviceSchema>;
// children: React.ReactNode;
// }>;
// export type SmartDeviceInstanceData = {
// devInfo: ReturnType<SmartDevices[ProductName]['getDevInfo']>;
// dpSchema: ReturnType<SmartDevices[ProductName]['getDpSchema']>;
// network: ReturnType<SmartDevices[ProductName]['getNetwork']>;
// bluetooth: ReturnType<SmartDevices[ProductName]['getBluetooth']>;
// };
// export function useProps(): SmartDevices[ProductName]['model']['props'];
// export function useProps<Value extends any>(
// selector: (props?: SmartDevices[ProductName]['model']['props']) => Value,
// equalityFn?: (a: Value, b: Value) => boolean
// ): Value;
// export function useDevice(): SmartDeviceInstanceData;
// export function useDevice<Device extends any>(
// selector: (device: SmartDeviceInstanceData) => Device,
// equalityFn?: (a: Device, b: Device) => boolean
// ): Device;
export function useActions(): SmartDevices[ProductName]['model']['actions'];
}
This source diff could not be displayed because it is too large. You can view the blob instead.
This source diff could not be displayed because it is too large. You can view the blob instead.
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment