Commit 5d90726b by Tonk

add McbLink screen

parent bb3838c6
...@@ -15,6 +15,7 @@ import { BottomNavigation, BottomNavigationTab } from 'react-native-ui-kitten'; ...@@ -15,6 +15,7 @@ import { BottomNavigation, BottomNavigationTab } from 'react-native-ui-kitten';
import SmartMeterScreen from './screens/Private/SmartMeterScreen/SmartMeterScreen'; import SmartMeterScreen from './screens/Private/SmartMeterScreen/SmartMeterScreen';
import SmartMeterDetailScreen from './screens/Private/SmartMeterScreen/SmartMeterDetailScreen'; import SmartMeterDetailScreen from './screens/Private/SmartMeterScreen/SmartMeterDetailScreen';
import CameraScreen from './screens/Private/CameraScreen'; import CameraScreen from './screens/Private/CameraScreen';
import McbLinkScreen from './screens/Private/SmartMeterScreen/McbLinkScreen';
// Timer // Timer
import TimerScreen from './screens/Private/TimerScreen/TimerScreen'; import TimerScreen from './screens/Private/TimerScreen/TimerScreen';
...@@ -74,6 +75,15 @@ const SmartMeterStack = createStackNavigator( ...@@ -74,6 +75,15 @@ const SmartMeterStack = createStackNavigator(
defaultNavigationOptions, defaultNavigationOptions,
} }
); );
const McbStack = createStackNavigator(
{
McbLink: McbLinkScreen,
},
{
headerLayoutPreset: 'center',
defaultNavigationOptions,
}
);
const CameraStack = createStackNavigator( const CameraStack = createStackNavigator(
{ {
...@@ -229,6 +239,7 @@ const MainStack = createStackNavigator( ...@@ -229,6 +239,7 @@ const MainStack = createStackNavigator(
Home: HomeStack, Home: HomeStack,
WithBottomTab: WithBottomTabStack, WithBottomTab: WithBottomTabStack,
Camera: CameraStack, Camera: CameraStack,
McbLink: McbStack,
}, },
{ {
defaultNavigationOptions: { header: null }, defaultNavigationOptions: { header: null },
......
...@@ -99,6 +99,8 @@ PODS: ...@@ -99,6 +99,8 @@ PODS:
- React - React
- RNReanimated (1.2.0): - RNReanimated (1.2.0):
- React - React
- RNScreens (2.0.0-alpha.3):
- React
- RNSVG (9.8.4): - RNSVG (9.8.4):
- React - React
- RNVectorIcons (6.6.0): - RNVectorIcons (6.6.0):
...@@ -133,6 +135,7 @@ DEPENDENCIES: ...@@ -133,6 +135,7 @@ DEPENDENCIES:
- "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)" - "RNCAsyncStorage (from `../node_modules/@react-native-community/async-storage`)"
- RNGestureHandler (from `../node_modules/react-native-gesture-handler`) - RNGestureHandler (from `../node_modules/react-native-gesture-handler`)
- RNReanimated (from `../node_modules/react-native-reanimated`) - RNReanimated (from `../node_modules/react-native-reanimated`)
- RNScreens (from `../node_modules/react-native-screens`)
- RNSVG (from `../node_modules/react-native-svg`) - RNSVG (from `../node_modules/react-native-svg`)
- RNVectorIcons (from `../node_modules/react-native-vector-icons`) - RNVectorIcons (from `../node_modules/react-native-vector-icons`)
- yoga (from `../node_modules/react-native/ReactCommon/yoga`) - yoga (from `../node_modules/react-native/ReactCommon/yoga`)
...@@ -196,6 +199,8 @@ EXTERNAL SOURCES: ...@@ -196,6 +199,8 @@ EXTERNAL SOURCES:
:path: "../node_modules/react-native-gesture-handler" :path: "../node_modules/react-native-gesture-handler"
RNReanimated: RNReanimated:
:path: "../node_modules/react-native-reanimated" :path: "../node_modules/react-native-reanimated"
RNScreens:
:path: "../node_modules/react-native-screens"
RNSVG: RNSVG:
:path: "../node_modules/react-native-svg" :path: "../node_modules/react-native-svg"
RNVectorIcons: RNVectorIcons:
...@@ -232,6 +237,7 @@ SPEC CHECKSUMS: ...@@ -232,6 +237,7 @@ SPEC CHECKSUMS:
RNCAsyncStorage: 2e2e3feb9bdadc752a026703d8c4065ca912e75a RNCAsyncStorage: 2e2e3feb9bdadc752a026703d8c4065ca912e75a
RNGestureHandler: 4cb47a93019c1a201df2644413a0a1569a51c8aa RNGestureHandler: 4cb47a93019c1a201df2644413a0a1569a51c8aa
RNReanimated: 1b52415c4302f198cb581282a0166690bad62c43 RNReanimated: 1b52415c4302f198cb581282a0166690bad62c43
RNScreens: 402a99b0a27c0c32f079cec12d3ccbd35e20cd7f
RNSVG: a78b4c581e33a1bb72968997d167afabf72b05dc RNSVG: a78b4c581e33a1bb72968997d167afabf72b05dc
RNVectorIcons: 0bb4def82230be1333ddaeee9fcba45f0b288ed4 RNVectorIcons: 0bb4def82230be1333ddaeee9fcba45f0b288ed4
yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411 yoga: 312528f5bbbba37b4dcea5ef00e8b4033fdd9411
......
import React from 'react';
import { Text, Tab, Tabs, ScrollableTab, View, Card, Icon } from 'native-base';
import { connect } from 'react-redux';
import { StyleSheet } from 'react-native';
import { theme, color } from '../../../constants/Styles';
import { HeaderButtons, Item } from 'react-navigation-header-buttons';
import IoniconsHeaderButton from '../../../components/IoniconsHeaderButton';
import { Switch, FlatList, ScrollView, TouchableWithoutFeedback, TouchableOpacity } from 'react-native-gesture-handler';
import { width } from '../../../constants/Layout';
import { getCurrentSelectedShadow, setSubBreakerStatus } from '../../../reduxStore/actions/currentSelectedAction';
const mockElec = [
{ name: 'elec1', icon: { type: 'Entypo', name: 'laptop' } },
{ name: 'elec2', icon: { type: '', name: '' } },
{ name: 'elec3', icon: { type: '', name: '' } },
{ name: 'elec4', icon: { type: '', name: '' } },
{ name: 'elec5', icon: { type: '', name: '' } },
{ name: 'elec1', icon: { type: '', name: '' } },
{ name: 'elec2', icon: { type: '', name: '' } },
{ name: 'elec1', icon: { type: 'Entypo', name: 'laptop' } },
{ name: 'elec2', icon: { type: '', name: '' } },
];
let checkedTimes = 0;
class McbLinkScreen extends React.Component {
static navigationOptions = ({ navigation }) => {
return {
title: navigation.getParam('mcbLink').name,
headerLeft: (
<HeaderButtons HeaderButtonComponent={IoniconsHeaderButton}>
<Item
title="back"
iconName="ios-arrow-back"
onPress={() => navigation.navigate('SmartMeterDetail')}
/>
</HeaderButtons>
),
headerStyle: {
backgroundColor: color.primary,
borderColor: 'transparent',
borderBottomWidth: 0,
shadowOffset: { height: 0, width: 0 },
shadowOpacity: 0,
elevation: 0,
},
};
};
state = {
subBreakersInfo: [],
subBreakerStatus: [],
toggleDel: false,
isWaiting: false,
};
componentDidMount = () => {
this.setSubBreakersState();
};
componentDidUpdate = (prevProps, prevState) => {
if (prevProps.existedSubBreakersData !== this.props.existedSubBreakersData) {
this.setSubBreakersState();
}
};
setSubBreakersState = () => {
const { existedSubBreakersData, shadow } = this.props;
const mcbIndex = this.props.navigation.getParam('mcbIndex');
const status = shadow[`ML${mcbIndex + 1}`];
this.setState({ subBreakersInfo: existedSubBreakersData[mcbIndex], subBreakerStatus: status });
};
formatData(start, end) {
let data = mockElec; //Electronic devices data
const numberOfFullRows = Math.floor(data.length / 4);
let numberOfElementsLastRow = data.length - numberOfFullRows * 4;
while (numberOfElementsLastRow !== 4 && numberOfElementsLastRow !== 0) {
if (!data.find(x => x.name === 'add')) {
data.push({ name: 'add', icon: { type: 'Ionicons', name: 'ios-add-circle' } });
} else {
data.push({ name: 'empty', icon: { type: '', name: '' } });
}
numberOfElementsLastRow = numberOfElementsLastRow + 1;
}
return data.slice(start, end);
}
renderSubbreaker = (item, index) => {
const mcbIndex = this.props.navigation.getParam('mcbIndex');
const handleOnPressSubBreakerSwitch = async value => {
this.setState({ isWaiting: true });
await this.props.setSubBreakerStatus(value, mcbIndex, index);
await this.props.getCurrentSelectedShadow();
const getShadowInterval = setInterval(async () => {
console.log('getShadow');
this.setState(() => {
if (this.props.desiredBreakerStatus === this.props.breakerStatus) {
console.log('Interval HandletoggleSubBreaker');
clearInterval(getShadowInterval);
return { isWaiting: false };
} else {
if (checkedTimes >= 2) {
clearInterval(getShadowInterval);
checkedTimes = 0;
}
return { isWaiting: false };
}
});
console.log('checkedTimes', checkedTimes);
++checkedTimes;
await this.props.getCurrentSelectedShadow();
this.setSubBreakersState();
}, 3000);
};
const { subBreakerStatus, isWaiting } = this.state;
const subStatus = subBreakerStatus[`L${mcbIndex + 1}B${index + 1}`] === 0 ? false : true;
return (
<View style={[theme.container, theme.containerWithPadding]}>
<Card style={{ borderRadius: 10, padding: 10, paddingHorizontal: 15 }}>
<View style={[theme.rowContainer, { justifyContent: 'space-between' }]}>
<Text style={[theme.smallTitle, theme.textDark]}>{item.name}</Text>
<Switch
disabled={isWaiting ? true : false}
value={subStatus}
onValueChange={value => handleOnPressSubBreakerSwitch(value)}
/>
</View>
<Text style={[theme.smDescription, theme.mt1]}>{item.description}</Text>
</Card>
{this.renderElectronic()}
</View>
);
};
renderElectronic = () => {
const { toggleDel } = this.state;
const renderScroll = () => {
const maxPage = Math.ceil(mockElec.length / 8);
const item = [];
for (let index = 0; index < maxPage; index++) {
let start = index * 8;
let end = (index + 1) * 8;
item.push(
<FlatList
style={[theme.mt1, { width: width - 30, paddingTop: 5 }]}
data={this.formatData(start, end)}
numColumns={4}
renderItem={({ item, index }) => {
if (item.name == 'empty') {
return (
<Card
transparent
style={[styles.electronicCard]} //(index + 1) % 4 ? 20 : 0
/>
);
} else if (item.name === 'add') {
return (
<Card style={[styles.electronicCard, { backgroundColor: color.lightGrey }]}>
<Icon
style={[styles.electronicIcon, { color: color.white }]}
name={item.icon.name}
/>
<Text style={[styles.electronictext, { color: color.white }]}>{item.name}</Text>
</Card>
);
} else {
return (
<>
<Card style={[styles.electronicCard]}>
<TouchableOpacity
onLongPress={() => this.setState({ toggleDel: true })}
style={theme.centerContainer}
>
<Icon
style={[styles.electronicIcon]}
type={item.icon.type || 'Ionicons'}
name={item.icon.name}
/>
<Text style={styles.electronictext}>{item.name}</Text>
</TouchableOpacity>
{toggleDel && (
<Icon
name="cancel"
type="MaterialIcons"
style={{
position: 'absolute',
top: -10,
left: -10,
color: color.lightGrey,
}}
onPress={() => console.log('delete electronic device')}
/>
)}
</Card>
</>
);
}
}}
ItemSeparatorComponent={() => <View style={{ margin: 5 }}></View>}
/>
);
}
return <>{item}</>;
};
return (
<>
<View style={[theme.rowContainer, theme.mt2, { justifyContent: 'space-between' }]}>
<Text style={[theme.normalText, theme.textDark]}>Electronics</Text>
{toggleDel ? (
<TouchableOpacity
style={{
backgroundColor: color.lightGrey,
borderRadius: 100,
paddingVertical: 2,
paddingHorizontal: 10,
}}
onPress={() => this.setState({ toggleDel: false })}
>
<Text style={[theme.smDescription, { color: color.white }]}>Done</Text>
</TouchableOpacity>
) : (
<Text style={theme.smDescription}>Edit</Text>
)}
</View>
<ScrollView horizontal pagingEnabled>
{renderScroll()}
</ScrollView>
</>
);
};
render() {
const subIndex = this.props.navigation.getParam('subIndex');
const { subBreakersInfo } = this.state;
const TabStyle = {
textStyle: [theme.description, theme.textWhite],
activeTextStyle: [theme.description, theme.textDanger],
tabStyle: {
backgroundColor: 'transparent',
borderRadius: 100,
marginVertical: 10,
paddingHorizontal: 10,
},
activeTabStyle: {
backgroundColor: color.white,
borderRadius: 100,
marginVertical: 10,
marginHorizontal: 5,
},
style: { backgroundColor: color.defaultBg },
};
return (
<Tabs
tabBarUnderlineStyle={{ backgroundColor: 'transparent' }}
renderTabBar={() => <ScrollableTab style={styles.scrollTab} />}
initialPage={subIndex}
>
{subBreakersInfo.map((item, index) => (
<Tab heading={item.name} {...TabStyle} key={`tab${index}`}>
{this.renderSubbreaker(item, index)}
</Tab>
))}
</Tabs>
);
}
}
const styles = StyleSheet.create({
scrollTab: {
borderWidth: 0,
backgroundColor: color.primary,
borderBottomEndRadius: 6,
borderBottomStartRadius: 6,
height: 60,
},
electronicCard: {
flex: 1,
aspectRatio: 1,
borderRadius: 10,
marginRight: 10,
marginLeft: 10,
alignItems: 'center',
justifyContent: 'center',
},
electronicIcon: {
color: color.primary,
},
electronictext: {
fontSize: 10,
fontFamily: 'Avenir-Roman',
color: color.grey,
// position: 'absolute',
// bottom: 5,
},
});
const mapStateToProps = state => ({
existedSubBreakersData: state.timersReducer.existedSubBreakersData,
shadow: state.currentSelectedDeviceReducer.shadow,
breakerStatus: state.currentSelectedDeviceReducer.breakerStatus,
desiredBreakerStatus: state.currentSelectedDeviceReducer.desiredBreakerStatus,
});
const mapDispatchToProps = {
setSubBreakerStatus,
getCurrentSelectedShadow,
};
export default connect(
mapStateToProps,
mapDispatchToProps
)(McbLinkScreen);
...@@ -331,7 +331,15 @@ class SmartMeterDetailScreen extends Component { ...@@ -331,7 +331,15 @@ class SmartMeterDetailScreen extends Component {
backgroundColor: 'rgba(216,216,216,0.1)', backgroundColor: 'rgba(216,216,216,0.1)',
}} }}
> >
<Row> <Row
onPress={() =>
this.props.navigation.navigate('McbLink', {
mcbLink: mcbLink,
mcbIndex: indexMcbLinks,
subIndex: indexSubBreakers,
})
}
>
<Left style={{ flex: 4 }}> <Left style={{ flex: 4 }}>
<View> <View>
<Text style={[theme.normalText, theme.textDark]}> <Text style={[theme.normalText, theme.textDark]}>
...@@ -343,7 +351,9 @@ class SmartMeterDetailScreen extends Component { ...@@ -343,7 +351,9 @@ class SmartMeterDetailScreen extends Component {
}]` }]`
: `Sub Breaker ${indexSubBreakers + 1}`} : `Sub Breaker ${indexSubBreakers + 1}`}
</Text> </Text>
<Text style={theme.description}>{subBreaker.description}</Text> <Text style={theme.description} numberOfLines={1}>
{subBreaker.description}
</Text>
</View> </View>
</Left> </Left>
<Right> <Right>
......
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