Last Updated on : 2024-06-05 03:14:29download
This article mainly takes ipcBasic as an example to introduce the rapid development of IPC custom panels, and introduce its specific functions and how to use them. For more resources, please go to tuya-panel-demo Github repository.
Remarks: This project depends on
TYSdk.mobile.mobileInfo.appRnVersion
5.31 or above. If the App version is too low, please go to Tuya Panel-RN to download again.
The template project is React Native 0.59 version TS, based on @tuya-smart/tuya-panel-ipc-sdk to encapsulate Player components and functional modules, and quickly develop panels related to IPC
Path Alias
React、Redux、Hooks
Note: This article only describes the scaffold-related directories. For general directory structure information, please refer to the RN 0.59 scaffolding document.
├── .babelrc
├── .eslintignore
├── .eslintrc.js
├── .gitignore
├── .npmrc
├── .prettierignore
├── .prettierrc.js
├── .versionrc
├── CHANGELOG.md
├── README-zh_CN.md
├── README.md
├── index.android.js // Android entrance
├── index.ios.js // Ios entrance
├── index.js
├── package.json
├── rn-cli.config.js
├── src
│ ├── api // Place a series of cloud APIs used in the project
│ ├── components
│ │ ├── connect.tsx
│ │ ├── index.ts // Component unified management entrance
│ │ ├── liveBottomBar
│ │ │ ├── customFeature
│ │ │ │ └── dialogCustomExample.tsx // Custom pop-up demo component
│ │ │ ├── liveControlBasic.tsx
│ │ │ └── liveGrid.tsx
│ │ ├── livePlayComponents
│ │ └── publicComponents // Public component
│ ├── composeLayout.tsx // The package handles some device events and device information needed inside the panel
│ ├── config
│ │ ├── cameraData.ts // Panel public data
│ │ ├── commonClick.ts // Custom method set
│ │ ├── commonConfig.ts // Common basic configuration, such as isIos
│ │ ├── commonInterface.ts // Public Ts type definition
│ │ ├── global.ts // Global variable configuration
│ │ ├── gridFeatureInitData.ts // Raster function data configuration
│ │ ├── index.ts
│ │ ├── panelBasicFeature.ts // Basic menu function configuration
│ │ ├── popDataStore.tsx // Functional components, enumerated module configuration center
│ │ └── theme.ts // Basic components and custom theme configuration
│ ├── i18n // Multilingual configuration
│ ├── main.tsx //Project entry file, routing configuration
│ ├── models
│ │ └── modules
│ │ ├── common.ts // Basic public redux configuration file
│ │ ├── ipcCommon.ts // Custom redux configuration file
│ │ └── theme.ts // Theme redux configuration file
│ ├── pages // Page-level management entry
│ ├── res // Local resources, including pictures, svg path, etc.
│ └── utils // Tools menu
│ └── index.ts
├── tsconfig.json
└── yarn.lock
This template supports the following features
If you need to develop support for more categories or custom features, please refer to Basic Kit, IPC component library document, For a detailed analysis of template catalog, please refer to RN 0.59 TS
Directory: pages/livePlay/Live-player-view.tsx
import { TYIpcPlayer } from '@tuya-smart/tuya-panel-ipc-sdk';
<View style={styles.livePlayerViewPage}>
<TYIpcPlayer
// Whether full screen
isFullScreen={isFullScreen}
// Listen for full screen call events
onChangeScreenOrientation={onChangeScreenOrientation}
// Full screen player width
fullPlayerWidth={fullPlayerWidth}
// Full screen player height
fullPlayerHeight={fullPlayerHeight}
// Is the device online
deviceOnline={devInfo.deviceOnline}
// Is it a privacy mode
privateMode={dpState.basic_private}
// Monitor the loading status of the video stream
onChangeStreamStatus={onChangeStreamStatus}
// Whether the monitoring device supports intercom and intercom mode
onChangeSupportedMicWay={onChangeSupportedMicWay}
// Monitor intercom switching sound
onListenTalkingChangeMute={onListenTalkingChangeMute}
// Monitor whether it is talking
onListenIsTalking={onListenIsTalking}
// Monitor whether it is recording
onChangeRecording={onChangeRecording}
// Sound state
voiceStatus={ipcCommonState.voiceStatus}
// Clarity value
clarityStatus={ipcCommonState.clarityStatus}
// Non-full screen component array
renderNormalComArr={cameraData.normalArr}
// Full screen component array
renderFullComArr={cameraData.fullComArr}
// Whether to hide the full screen menu
hideFullMenu={hideFullMenu}
// Whether to stop full screen animation
stopFullAnim={ipcCommonState.stopFullAnim}
// Full screen click event
onFullScreenTapView={onFullScreenTapView}
// Take a screenshot to enter the album entrance event
pressEnterAlbum={() => {
commonClick.toggleNativePage('paramAlbum');
}}
// Monitor the video stream screen ratio whether to press the height and the ratio
onChangeZoomStatus={onChangeZoomStatus}
// Video default magnification
scaleMultiple={scaleStatus}
// Screen capture popup style
cutStyle={cutStyle}
// Whether to show custom video mask
showCustomVideoLoad={ipcCommonState.showCustomVideoLoad}
// Custom video mask text
showCustomVideoText={ipcCommonState.showCustomVideoText}
// Video timing style
timerInterValStyle={timerInterValStyle}
// Two-way intercom call prompt
twoMicStyle={twoMicStyle}
/>
</View>
For more functions of the player, please refer to Player Components, Player function library
Such as full screen, screenshot, intercom, recording, pull down
Directory: componets/liveBottomBar/liveControlBasic.tsx
// UI display
<View key={item.key} style={item.show ? { flex: 1 } : { width: 0 }}>
...
{item.key === 'mic' && renderMicBtn(item)}
{item.key !== 'mic' && renderNotMicBtn(item)}
</View>
Directory: config/panelBasicFeature.ts
// Data configuration
const getBasicMenuData = (nextProps: any, openMoreControl: boolean) => {
const initMenu: any = [
{
show: true,
key: 'fullScreen',
test: 'tuya_ipc_fullscreen',
imgSource: Res.publicImage.basicFullScreen,
},
...
{
show: true,
test: 'tuya_ipc_basic_expand',
key: 'more',
imgSource: openMoreControl
? Res.publicImage.basicFeatureOpen
: Res.publicImage.basicFeatureClose,
},
];
return initMenu;
};
Custom added separate modules such as playback, infrared night vision, etc.
Directory: config/gridFeatureInitData.ts
The main purpose is to classify module functions to facilitate data maintenance and development, and can also be customized and extended。
Mainly divided into 5 categories, namely
const getGridMenu = (schema, isSupportCloudStorage) => [
{
show: schema.sd_status !== undefined,
key: 'sd_status',
imgSource: Res.customFeature.dpSdStatus,
imgTitle: Strings.getLang('ipc_panel_button_playBack'),
type: 'basic',
shareOpen: true,
},
...
];
Generally related to IPC devices, mainly using Player function library Provide API to complete the development, most of which are directly jump to the native page component
Directory: config/commonClick.ts
const toggleNativePage = (key: string, time?: any) => {
if (isRecordingNow() || isMicTalking()) {
return false;
}
const state = store.getState();
const { type } = state.theme;
// Jump to the original theme color, the defined black value is 1, white is 2 and the default is 0
const nativeThemeValue = type === 'dark' ? 1 : 2;
const sendParam: NativeParamInter = { theme: nativeThemeValue };
time !== undefined && (sendParam.time = time);
switch (key) {
case 'paramPlayBack':
TYIpcNative.enterParamPlayBack(sendParam);
break;
...
default:
break;
}
};
Generally, it is related to the Boolean type of DP point. The click event triggers the release of the corresponding DP point. There are also some special DPs. For example, the private mode needs to actively disconnect the video stream while sending the DP.
Directory: components/liveBottomBar/liveGrid.tsx
import { TYSdk } from 'tuya-panel-kit';
const TYDevice = TYSdk.device;
...
const sendValue = !dpState[key];
if (key === 'basic_private') {
if (commonClick.isRecordingNow() || commonClick.isMicTalking()) {
return false;
}
}
TYDevice.putDeviceData({
[key]: sendValue,
});
...
Generally, the DP point type is related to enumeration or custom enumeration (theme switching, etc.), the pop-up window displays the current enumeration value and DP issuance
Directory: components/liveBottomBar/liveGrid.tsx
// The data is stored in Redux, and the public component switchDialog displays the corresponding value
if (fatureType === 'switchDialog') {
commonClick.savePopDataToRedux(key, dpState[key]);
}
Enumerated data configuration
Directory: config/popDataStore.tsx
export const popDataSchema = {
// actived means to display the activated tintColor when the dp point value is the same as the Value value
// Theme color
generalTheme: {
title: Strings.getLang('ipc_panel_button_theme'),
showData: [
{ value: 'light', text: Strings.getLang('ipc_panel_theme_light'), actived: false },
{ value: 'dark', text: Strings.getLang('ipc_panel_theme_dark'), actived: false },
],
},
// Night vision switch
basic_nightvision: {
title: Strings.getLang('ipc_nightvision_button'),
showData: [
{ value: '0', text: Strings.getLang('dp_basic_nightvision_auto'), actived: true },
{ value: '1', text: Strings.getLang('dp_basic_nightvision_off'), actived: false },
{ value: '2', text: Strings.getLang('dp_basic_nightvision_on'), actived: true },
],
},
};
Any module is displayed as a pop-up window
Directory: components/liveBottomBar/liveGrid.tsx
// The data is stored in Redux, and the common component customDialog displays the corresponding components
if (fatureType === 'customDialog') {
commonClick.saveCustomDialogDataToRedux(key);
}
Component data configuration
Directory: config/popDataStore.tsx
export const popDataSchema = {
// The title is null, you need to write the title in the component yourself, which means that the title is dynamically changed, so as to avoid page jitter in the process of changing the title.
// Custom bullet frame
customDialogFeat1: {
title: Strings.getLang('ipc_panel_button_custom_dialog'),
component: <DialogCustomExample />,
},
Any module needs to jump to a new page
A fixed API is required to jump to a new level page and return to the preview interface, please refer to the document Player Function Library
Directory: components/liveBottomBar/liveGrid.tsx
if (fatureType === 'switchPage') {
key === 'rnCustomPage' && commonClick.enterFirstRnPage('customPage');
}
Directory: config/commonClick.ts
import { TYIpcNative } from '@tuya-smart/tuya-panel-ipc-sdk';
const enterFirstRnPage = (id: string, data?: any) => {
if (isRecordingNow() || isMicTalking()) {
return false;
}
Popup.close();
store.dispatch(actions.ipcCommonActions.showCustomDialog({ showCustomDialog: false }));
store.dispatch(actions.ipcCommonActions.showPopCommon({ showPopCommon: false }));
TYIpcNative.enterRnPage(id, data);
};
Is this page helpful?
YesFeedbackIs this page helpful?
YesFeedback