IPC Basic Template

Last Updated on : 2023-10-12 08:00:16download

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.

Introduction

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

IPC Basic Template

Table of Contents

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

Features

This template supports the following features

  • IPC basic functions: preview, record, screenshot, intercom
  • IPC function expansion: playback, cloud storage, photo album
  • DP point function: theme color matching, privacy mode, infrared night vision
  • Custom function: custom popup, custom page

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

Function development

1. Player introduction

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

2. Basic Function

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;
};

3. Function Menu Module

Custom added separate modules such as playback, infrared night vision, etc.

3.1 Data Configuration

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

  • basic (Basic modules, functional modules related to IPC, such as playback, cloud storage, photo albums)
  • switch (DP function, type is Boolean)
  • swichDialog (DP function, type is enumerated)
  • customDialog (Custom pop-up function)
  • switchPage(Custom page function)
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,
  },
  ...
];

3.2 Basic Module

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;
  }
};

3.3 Switch Module

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,
  });
...

3.4 SwitchDialog Module

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 },
    ],
  },
};

3.5 CustomDialog Module

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 />,
  },

3.6 SwitchPage Module

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);
};