style: lint fix
This commit is contained in:
parent
facbf56d2d
commit
b71eea4560
83
App.js
83
App.js
@ -3,12 +3,11 @@
|
||||
* https://github.com/facebook/react-native
|
||||
*
|
||||
* @format
|
||||
* @flow
|
||||
*/
|
||||
|
||||
import React from 'react';
|
||||
import { createAppContainer } from 'react-navigation';
|
||||
import { createStackNavigator } from 'react-navigation-stack';
|
||||
import {createAppContainer} from 'react-navigation';
|
||||
import {createStackNavigator} from 'react-navigation-stack';
|
||||
|
||||
import MainScreen from './src/screen/MainScreen';
|
||||
import CardEditScreen from './src/screen/CardEditScreen';
|
||||
@ -18,58 +17,60 @@ import i18n from 'i18n-js';
|
||||
import en from './src/locales/en';
|
||||
import ko from './src/locales/ko';
|
||||
|
||||
const MainNavigator = createStackNavigator({
|
||||
Home: {
|
||||
screen: MainScreen,
|
||||
navigationOptions: {headerShown: false}
|
||||
const MainNavigator = createStackNavigator(
|
||||
{
|
||||
Home: {
|
||||
screen: MainScreen,
|
||||
navigationOptions: {headerShown: false},
|
||||
},
|
||||
CardEditScreen: {
|
||||
screen: CardEditScreen,
|
||||
navigationOptions: {headerShown: false},
|
||||
},
|
||||
},
|
||||
CardEditScreen: {
|
||||
screen: CardEditScreen,
|
||||
navigationOptions: {headerShown: false}
|
||||
{
|
||||
initialRouteName: 'Home',
|
||||
},
|
||||
},
|
||||
{
|
||||
initialRouteName: 'Home',
|
||||
}
|
||||
);
|
||||
|
||||
const AppContainer = createAppContainer(MainNavigator);
|
||||
|
||||
const setI18nConfig = () => {
|
||||
const fallback = { languageTag: 'en' };
|
||||
const { languageTag } = RNLocalize.findBestAvailableLanguage(['en', 'ko']) || fallback;
|
||||
const fallback = {languageTag: 'en'};
|
||||
const {languageTag} =
|
||||
RNLocalize.findBestAvailableLanguage(['en', 'ko']) || fallback;
|
||||
|
||||
i18n.translations = {
|
||||
en,
|
||||
ko,
|
||||
en,
|
||||
ko,
|
||||
};
|
||||
i18n.locale = languageTag;
|
||||
};
|
||||
|
||||
export default class App extends React.Component{
|
||||
constructor(props) {
|
||||
super(props);
|
||||
setI18nConfig();
|
||||
}
|
||||
export default class App extends React.Component {
|
||||
constructor(props) {
|
||||
super(props);
|
||||
setI18nConfig();
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
RNLocalize.addEventListener('change', this.handleLocalizationChange)
|
||||
}
|
||||
componentDidMount() {
|
||||
RNLocalize.addEventListener('change', this.handleLocalizationChange);
|
||||
}
|
||||
|
||||
componentWillUnmount() {
|
||||
RNLocalize.removeEventListener('change', this.handleLocalizationChange)
|
||||
}
|
||||
componentWillUnmount() {
|
||||
RNLocalize.removeEventListener('change', this.handleLocalizationChange);
|
||||
}
|
||||
|
||||
handleLocalizationChange = () => {
|
||||
setI18nConfig();
|
||||
this.forceUpdate();
|
||||
};
|
||||
handleLocalizationChange = () => {
|
||||
setI18nConfig();
|
||||
this.forceUpdate();
|
||||
};
|
||||
|
||||
render(){
|
||||
return (
|
||||
<>
|
||||
<AppContainer/>
|
||||
</>
|
||||
);
|
||||
}
|
||||
};
|
||||
render() {
|
||||
return (
|
||||
<>
|
||||
<AppContainer />
|
||||
</>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -1,39 +1,41 @@
|
||||
|
||||
export default {
|
||||
header_home: 'Home',
|
||||
header_add: 'Add',
|
||||
header_edit: 'Edit',
|
||||
header_home: 'Home',
|
||||
header_add: 'Add',
|
||||
header_edit: 'Edit',
|
||||
|
||||
main_empty_string: 'Touch + button on top right to add a card',
|
||||
main_empty_string: 'Touch + button on top right to add a card',
|
||||
|
||||
edit_random: 'Random Generate',
|
||||
edit_preview: 'Preview',
|
||||
edit_sid_notice: 'SID is 16-digit hexadecimal number. Note that it is not a card number!',
|
||||
edit_random: 'Random Generate',
|
||||
edit_preview: 'Preview',
|
||||
edit_sid_notice:
|
||||
'SID is 16-digit hexadecimal number. Note that it is not a card number!',
|
||||
|
||||
edit_background: 'Background',
|
||||
edit_background_empty: 'Touch here to select the background image',
|
||||
edit_background_selected: 'The image has been selected',
|
||||
edit_background: 'Background',
|
||||
edit_background_empty: 'Touch here to select the background image',
|
||||
edit_background_selected: 'The image has been selected',
|
||||
|
||||
edit_name: 'Name',
|
||||
edit_name: 'Name',
|
||||
|
||||
alert_delete_title: 'Delete',
|
||||
alert_delete_content: 'Do you want to delete this card?',
|
||||
alert_delete_yes: 'Yes',
|
||||
alert_delete_no: 'No',
|
||||
alert_delete_title: 'Delete',
|
||||
alert_delete_content: 'Do you want to delete this card?',
|
||||
alert_delete_yes: 'Yes',
|
||||
alert_delete_no: 'No',
|
||||
|
||||
alert_save_content: 'Card saved successfully.',
|
||||
alert_save_yes: 'OK',
|
||||
alert_save_content: 'Card saved successfully.',
|
||||
alert_save_yes: 'OK',
|
||||
|
||||
alert_not_support_title: 'This device is not supported',
|
||||
alert_not_support_content: 'This device does not have the feature to emulate card.',
|
||||
alert_not_support_yes: 'OK',
|
||||
alert_not_support_title: 'This device is not supported',
|
||||
alert_not_support_content:
|
||||
'This device does not have the feature to emulate card.',
|
||||
alert_not_support_yes: 'OK',
|
||||
|
||||
alert_nfc_title: 'NFC is disabled',
|
||||
alert_nfc_content: 'NFC is required to emulate card. Please enable NFC in the settings and restart the app.',
|
||||
alert_nfc_yes: 'OK',
|
||||
alert_nfc_title: 'NFC is disabled',
|
||||
alert_nfc_content:
|
||||
'NFC is required to emulate card. Please enable NFC in the settings and restart the app.',
|
||||
alert_nfc_yes: 'OK',
|
||||
|
||||
card_touch_to_enable: 'Touch to enable',
|
||||
card_touch_to_disable: 'Touch to disable',
|
||||
card_delete: 'Delete',
|
||||
card_edit: 'Edit',
|
||||
}
|
||||
card_touch_to_enable: 'Touch to enable',
|
||||
card_touch_to_disable: 'Touch to disable',
|
||||
card_delete: 'Delete',
|
||||
card_edit: 'Edit',
|
||||
};
|
||||
|
@ -1,40 +1,40 @@
|
||||
|
||||
export default {
|
||||
header_home: '홈',
|
||||
header_add: '카드 추가',
|
||||
header_edit: '카드 편집',
|
||||
header_home: '홈',
|
||||
header_add: '카드 추가',
|
||||
header_edit: '카드 편집',
|
||||
|
||||
main_empty_string: '우측 상단의 +를 눌러 카드를 추가해주세요',
|
||||
main_empty_string: '우측 상단의 +를 눌러 카드를 추가해주세요',
|
||||
|
||||
edit_random: '랜덤 생성',
|
||||
edit_preview: '미리보기',
|
||||
edit_sid_notice: 'SID는 16진수 16자리 입니다. 카드 번호가 아님에 유의하세요!',
|
||||
edit_random: '랜덤 생성',
|
||||
edit_preview: '미리보기',
|
||||
edit_sid_notice: 'SID는 16진수 16자리 입니다. 카드 번호가 아님에 유의하세요!',
|
||||
|
||||
edit_background: '카드 배경',
|
||||
edit_background_empty: '여기를 눌러 사진을 선택할 수 있습니다.',
|
||||
edit_background_selected: '사진이 선택되었습니다.',
|
||||
edit_background: '카드 배경',
|
||||
edit_background_empty: '여기를 눌러 사진을 선택할 수 있습니다.',
|
||||
edit_background_selected: '사진이 선택되었습니다.',
|
||||
|
||||
edit_name: '카드 이름',
|
||||
edit_name: '카드 이름',
|
||||
|
||||
alert_delete_title: '삭제',
|
||||
alert_delete_content: '카드를 삭제하시겠습니까?',
|
||||
alert_delete_yes: '예',
|
||||
alert_delete_no: '아니오',
|
||||
alert_delete_title: '삭제',
|
||||
alert_delete_content: '카드를 삭제하시겠습니까?',
|
||||
alert_delete_yes: '예',
|
||||
alert_delete_no: '아니오',
|
||||
|
||||
alert_save_content: '카드를 저장했습니다.',
|
||||
alert_save_yes: '확인',
|
||||
alert_save_content: '카드를 저장했습니다.',
|
||||
alert_save_yes: '확인',
|
||||
|
||||
alert_not_support_title: '이 기기는 지원되지 않습니다.',
|
||||
alert_not_support_content: '이 기기는 카드를 에뮬레이션 하기 위해 필요한 기능을 가지고 있지 않습니다.',
|
||||
alert_not_support_yes: '확인',
|
||||
alert_not_support_title: '이 기기는 지원되지 않습니다.',
|
||||
alert_not_support_content:
|
||||
'이 기기는 카드를 에뮬레이션 하기 위해 필요한 기능을 가지고 있지 않습니다.',
|
||||
alert_not_support_yes: '확인',
|
||||
|
||||
alert_nfc_title: 'NFC가 활성화 되어있지 않습니다.',
|
||||
alert_nfc_content: '카드를 에뮬레이션 하기 위해서 NFC가 필요합니다. 설정에서 NFC를 활성화하고 앱을 재실행해주세요.',
|
||||
alert_nfc_yes: '확인',
|
||||
|
||||
card_touch_to_enable: '터치하여 활성화',
|
||||
card_touch_to_disable: '터치하여 비활성화',
|
||||
card_delete: '삭제',
|
||||
card_edit: '편집',
|
||||
}
|
||||
alert_nfc_title: 'NFC가 활성화 되어있지 않습니다.',
|
||||
alert_nfc_content:
|
||||
'카드를 에뮬레이션 하기 위해서 NFC가 필요합니다. 설정에서 NFC를 활성화하고 앱을 재실행해주세요.',
|
||||
alert_nfc_yes: '확인',
|
||||
|
||||
card_touch_to_enable: '터치하여 활성화',
|
||||
card_touch_to_disable: '터치하여 비활성화',
|
||||
card_delete: '삭제',
|
||||
card_edit: '편집',
|
||||
};
|
||||
|
@ -1,19 +1,19 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
StatusBar,
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
Dimensions,
|
||||
ImageBackground,
|
||||
findNodeHandle,
|
||||
Alert,
|
||||
StyleSheet,
|
||||
Image,
|
||||
KeyboardAvoidingView,
|
||||
TextInput,
|
||||
View,
|
||||
Text,
|
||||
StatusBar,
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
Dimensions,
|
||||
ImageBackground,
|
||||
findNodeHandle,
|
||||
Alert,
|
||||
StyleSheet,
|
||||
Image,
|
||||
KeyboardAvoidingView,
|
||||
TextInput,
|
||||
} from 'react-native';
|
||||
import update from 'react-addons-update';
|
||||
import Icon from 'react-native-vector-icons/MaterialIcons';
|
||||
@ -22,368 +22,547 @@ import CardConv from '../module/CardConv';
|
||||
import i18n from 'i18n-js';
|
||||
|
||||
class CardPreview extends React.Component {
|
||||
render() {
|
||||
let cardContent = (
|
||||
<View style={{flex: 1, backgroundColor:'rgba(0,0,0,0.3)', borderRadius:8}}>
|
||||
<View style={{flex: 1,}}>
|
||||
<TouchableOpacity style={{flex: 1}}>
|
||||
<Text style={{position: 'absolute', top: 20, left: 20, fontSize: 17, fontWeight:'bold', color:'#ffffff'}}>
|
||||
{this.props.name}
|
||||
</Text>
|
||||
<View style={{flex: 1, justifyContent:'center', paddingTop: 20,}}>
|
||||
<Text style={{paddingTop: 0, textAlign: 'center', alignSelf: 'center', color: '#E0E0E0', fontSize: 14 }}>
|
||||
{this.props.uid ?
|
||||
this.props.uid.substr(0,4)+'-'+this.props.uid.substr(4,4)+'-'+this.props.uid.substr(8,4)+'-'+this.props.uid.substr(12,4)
|
||||
: ''
|
||||
}
|
||||
</Text>
|
||||
<Text style={{paddingTop: 8, textAlign: 'center', alignSelf: 'center', fontSize: 24, color:'#FAFAFA', fontWeight: '500', letterSpacing:-0.5}}>
|
||||
{i18n.t('card_touch_to_enable')}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={{height: 1, backgroundColor: '#FAFAFA'}}/>
|
||||
<View style={{height: 48, flexDirection: 'row'}}>
|
||||
<TouchableOpacity style={{
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}>
|
||||
<Text style={{fontSize: 14, color:'#FAFAFA'}}>{i18n.t('card_edit')}</Text>
|
||||
</TouchableOpacity>
|
||||
<View style={{width: 1, backgroundColor: '#FAFAFA'}}/>
|
||||
<TouchableOpacity style={{
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}>
|
||||
<Text style={{fontSize: 14, color:'#ffffff'}}>{i18n.t('card_delete')}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
render() {
|
||||
let cardContent = (
|
||||
<View
|
||||
style={{flex: 1, backgroundColor: 'rgba(0,0,0,0.3)', borderRadius: 8}}>
|
||||
<View style={{flex: 1}}>
|
||||
<TouchableOpacity style={{flex: 1}}>
|
||||
<Text
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 20,
|
||||
left: 20,
|
||||
fontSize: 17,
|
||||
fontWeight: 'bold',
|
||||
color: '#ffffff',
|
||||
}}>
|
||||
{this.props.name}
|
||||
</Text>
|
||||
<View style={{flex: 1, justifyContent: 'center', paddingTop: 20}}>
|
||||
<Text
|
||||
style={{
|
||||
paddingTop: 0,
|
||||
textAlign: 'center',
|
||||
alignSelf: 'center',
|
||||
color: '#E0E0E0',
|
||||
fontSize: 14,
|
||||
}}>
|
||||
{this.props.uid
|
||||
? this.props.uid.substr(0, 4) +
|
||||
'-' +
|
||||
this.props.uid.substr(4, 4) +
|
||||
'-' +
|
||||
this.props.uid.substr(8, 4) +
|
||||
'-' +
|
||||
this.props.uid.substr(12, 4)
|
||||
: ''}
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
paddingTop: 8,
|
||||
textAlign: 'center',
|
||||
alignSelf: 'center',
|
||||
fontSize: 24,
|
||||
color: '#FAFAFA',
|
||||
fontWeight: '500',
|
||||
letterSpacing: -0.5,
|
||||
}}>
|
||||
{i18n.t('card_touch_to_enable')}
|
||||
</Text>
|
||||
</View>
|
||||
)
|
||||
return (
|
||||
<View style={[{
|
||||
borderRadius: 8,
|
||||
height: this.props.cardHeight,
|
||||
marginTop: 16,
|
||||
justifyContent: 'center',
|
||||
},]}>
|
||||
{this.props.image ? (
|
||||
<ImageBackground
|
||||
source={{uri: this.props.image}}
|
||||
style={{
|
||||
flex: 1,
|
||||
resizeMode:'contain',
|
||||
}}
|
||||
blurRadius={2}
|
||||
borderRadius={8}>
|
||||
{cardContent}
|
||||
</ImageBackground>
|
||||
) : (
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
resizeMode:'contain',
|
||||
backgroundColor: '#03A9F4',
|
||||
}}
|
||||
blurRadius={2}
|
||||
borderRadius={8}>
|
||||
{cardContent}
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={{height: 1, backgroundColor: '#FAFAFA'}} />
|
||||
<View style={{height: 48, flexDirection: 'row'}}>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}>
|
||||
<Text style={{fontSize: 14, color: '#FAFAFA'}}>
|
||||
{i18n.t('card_edit')}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<View style={{width: 1, backgroundColor: '#FAFAFA'}} />
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}>
|
||||
<Text style={{fontSize: 14, color: '#ffffff'}}>
|
||||
{i18n.t('card_delete')}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
{
|
||||
borderRadius: 8,
|
||||
height: this.props.cardHeight,
|
||||
marginTop: 16,
|
||||
justifyContent: 'center',
|
||||
},
|
||||
]}>
|
||||
{this.props.image ? (
|
||||
<ImageBackground
|
||||
source={{uri: this.props.image}}
|
||||
style={{
|
||||
flex: 1,
|
||||
resizeMode: 'contain',
|
||||
}}
|
||||
blurRadius={2}
|
||||
borderRadius={8}>
|
||||
{cardContent}
|
||||
</ImageBackground>
|
||||
) : (
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
resizeMode: 'contain',
|
||||
backgroundColor: '#03A9F4',
|
||||
}}
|
||||
blurRadius={2}
|
||||
borderRadius={8}>
|
||||
{cardContent}
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class ETextInput extends React.Component {
|
||||
state = {
|
||||
focused: false,
|
||||
value: this.props.value ?? '',
|
||||
};
|
||||
state = {
|
||||
focused: false,
|
||||
value: this.props.value ?? '',
|
||||
};
|
||||
|
||||
onFocusCallback(){
|
||||
this.setState({focused: true});
|
||||
if(typeof this.props.onFocus === 'function')
|
||||
this.props.onFocus();
|
||||
onFocusCallback() {
|
||||
this.setState({focused: true});
|
||||
if (typeof this.props.onFocus === 'function') {
|
||||
this.props.onFocus();
|
||||
}
|
||||
}
|
||||
|
||||
onBlurCallback(){
|
||||
this.setState({focused: false});
|
||||
if(typeof this.props.onBlur === 'function')
|
||||
this.props.onBlur();
|
||||
onBlurCallback() {
|
||||
this.setState({focused: false});
|
||||
if (typeof this.props.onBlur === 'function') {
|
||||
this.props.onBlur();
|
||||
}
|
||||
}
|
||||
|
||||
onChangeTextCallback(text){
|
||||
if(typeof this.props.filter === 'function')
|
||||
text = this.props.filter(text);
|
||||
if(typeof this.props.onChangeText === 'function')
|
||||
this.props.onChangeText(text);
|
||||
onChangeTextCallback(text) {
|
||||
if (typeof this.props.filter === 'function') {
|
||||
text = this.props.filter(text);
|
||||
}
|
||||
|
||||
focus(){
|
||||
this.textInput.focus();
|
||||
if (typeof this.props.onChangeText === 'function') {
|
||||
this.props.onChangeText(text);
|
||||
}
|
||||
}
|
||||
|
||||
render() {
|
||||
return (
|
||||
<View style={this.props.style}>
|
||||
<Text style={[{fontSize: 14,
|
||||
color: this.props.error ? '#F44336' : this.state.focused ? '#03A9F4' : '#9E9E9E',
|
||||
fontWeight: 'bold',
|
||||
}, this.props.titleStyle]}>
|
||||
{this.props.title}
|
||||
</Text>
|
||||
focus() {
|
||||
this.textInput.focus();
|
||||
}
|
||||
|
||||
<TextInput
|
||||
style={[{fontSize: 17, paddingTop: 4,}, this.props.textStyle]}
|
||||
value={this.props.value}
|
||||
onFocus={() => this.onFocusCallback()}
|
||||
onBlur={() => this.onBlurCallback()}
|
||||
onChangeText={text => this.onChangeTextCallback(text)}
|
||||
editable={this.props.editable}
|
||||
maxLength={this.props.maxLength}
|
||||
autoCapitalize={this.props.autoCapitalize}
|
||||
ref={ref => this.textInput = ref}
|
||||
>
|
||||
</TextInput>
|
||||
<View style={{
|
||||
paddingTop: 2,
|
||||
height: this.state.focused ? 2 : 1,
|
||||
backgroundColor: this.props.error ? '#F44336' : this.state.focused ? '#03A9F4' : '#9E9E9E',
|
||||
opacity: this.props.editable ? 1 : 0.5,
|
||||
}}/>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<View style={this.props.style}>
|
||||
<Text
|
||||
style={[
|
||||
{
|
||||
fontSize: 14,
|
||||
color: this.props.error
|
||||
? '#F44336'
|
||||
: this.state.focused
|
||||
? '#03A9F4'
|
||||
: '#9E9E9E',
|
||||
fontWeight: 'bold',
|
||||
},
|
||||
this.props.titleStyle,
|
||||
]}>
|
||||
{this.props.title}
|
||||
</Text>
|
||||
|
||||
<TextInput
|
||||
style={[{fontSize: 17, paddingTop: 4}, this.props.textStyle]}
|
||||
value={this.props.value}
|
||||
onFocus={() => this.onFocusCallback()}
|
||||
onBlur={() => this.onBlurCallback()}
|
||||
onChangeText={text => this.onChangeTextCallback(text)}
|
||||
editable={this.props.editable}
|
||||
maxLength={this.props.maxLength}
|
||||
autoCapitalize={this.props.autoCapitalize}
|
||||
ref={ref => (this.textInput = ref)}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
paddingTop: 2,
|
||||
height: this.state.focused ? 2 : 1,
|
||||
backgroundColor: this.props.error
|
||||
? '#F44336'
|
||||
: this.state.focused
|
||||
? '#03A9F4'
|
||||
: '#9E9E9E',
|
||||
opacity: this.props.editable ? 1 : 0.5,
|
||||
}}
|
||||
/>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class CardEditScreen extends React.Component {
|
||||
state = {
|
||||
name: this.props.navigation.getParam('name', ''),
|
||||
sidAll: this.props.navigation.getParam('sid', '02FE'),
|
||||
sid2: '',
|
||||
sid3: '',
|
||||
sid4: '',
|
||||
uid: '',
|
||||
sidError: false,
|
||||
state = {
|
||||
name: this.props.navigation.getParam('name', ''),
|
||||
sidAll: this.props.navigation.getParam('sid', '02FE'),
|
||||
sid2: '',
|
||||
sid3: '',
|
||||
sid4: '',
|
||||
uid: '',
|
||||
sidError: false,
|
||||
|
||||
image: this.props.navigation.getParam('image', ''),
|
||||
index: this.props.navigation.getParam('index', null), // null 이면 카드 새로 생성
|
||||
mode: '',
|
||||
image: this.props.navigation.getParam('image', ''),
|
||||
index: this.props.navigation.getParam('index', null), // null 이면 카드 새로 생성
|
||||
mode: '',
|
||||
|
||||
update: this.props.navigation.getParam('update', null),
|
||||
update: this.props.navigation.getParam('update', null),
|
||||
|
||||
cardFocused: 'false',
|
||||
cardFocused: 'false',
|
||||
};
|
||||
|
||||
componentDidMount(): void {
|
||||
let {height, width} = Dimensions.get('window');
|
||||
|
||||
function randomHex4Byte() {
|
||||
let hexString = Math.min(
|
||||
Math.floor(Math.random() * 65536),
|
||||
65535,
|
||||
).toString(16);
|
||||
|
||||
if (hexString.length < 4) {
|
||||
hexString = '0'.repeat(4 - hexString.length) + hexString;
|
||||
}
|
||||
|
||||
return hexString.toUpperCase();
|
||||
}
|
||||
|
||||
componentDidMount(): void {
|
||||
let {height, width} = (Dimensions.get('window'));
|
||||
|
||||
function randomHex4Byte(){
|
||||
let hexString = Math.min(Math.floor(Math.random() * 65536), 65535).toString(16);
|
||||
|
||||
if(hexString.length < 4)
|
||||
hexString = '0'.repeat(4 - hexString.length) + hexString;
|
||||
|
||||
return hexString.toUpperCase();
|
||||
}
|
||||
|
||||
|
||||
if(this.state.index === null){
|
||||
this.setState({mode: 'add', sid2: randomHex4Byte(), sid3: randomHex4Byte(), sid4: randomHex4Byte(), cardHeight: (width - 48) * 53.98 / 85.60,},
|
||||
() => this.updateSID());
|
||||
}
|
||||
else{
|
||||
this.setState({
|
||||
mode: 'edit',
|
||||
sid2: this.state.sidAll.substr(4, 4),
|
||||
sid3: this.state.sidAll.substr(8, 4),
|
||||
sid4: this.state.sidAll.substr(12, 4),
|
||||
cardHeight: (width - 48) * 53.98 / 85.60,
|
||||
}, () => {
|
||||
this.updateSID();
|
||||
});
|
||||
}
|
||||
|
||||
this.nameInput.focus();
|
||||
if (this.state.index === null) {
|
||||
this.setState(
|
||||
{
|
||||
mode: 'add',
|
||||
sid2: randomHex4Byte(),
|
||||
sid3: randomHex4Byte(),
|
||||
sid4: randomHex4Byte(),
|
||||
cardHeight: ((width - 48) * 53.98) / 85.6,
|
||||
},
|
||||
() => this.updateSID(),
|
||||
);
|
||||
} else {
|
||||
this.setState(
|
||||
{
|
||||
mode: 'edit',
|
||||
sid2: this.state.sidAll.substr(4, 4),
|
||||
sid3: this.state.sidAll.substr(8, 4),
|
||||
sid4: this.state.sidAll.substr(12, 4),
|
||||
cardHeight: ((width - 48) * 53.98) / 85.6,
|
||||
},
|
||||
() => {
|
||||
this.updateSID();
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
makeSid(){
|
||||
let sid = '02FE' + this.state.sid2 + this.state.sid3 + this.state.sid4;
|
||||
sid = sid.toUpperCase();
|
||||
if(sid.length !== 16){
|
||||
return '';
|
||||
}
|
||||
if(sid.replace(/[^0-9A-F]/g, '') !== sid){
|
||||
return '';
|
||||
}
|
||||
this.nameInput.focus();
|
||||
}
|
||||
|
||||
return sid;
|
||||
makeSid() {
|
||||
let sid = '02FE' + this.state.sid2 + this.state.sid3 + this.state.sid4;
|
||||
sid = sid.toUpperCase();
|
||||
if (sid.length !== 16) {
|
||||
return '';
|
||||
}
|
||||
if (sid.replace(/[^0-9A-F]/g, '') !== sid) {
|
||||
return '';
|
||||
}
|
||||
|
||||
async updateSID(){
|
||||
if(this.makeSid() !== ''){
|
||||
let uid = await CardConv.convertSID(this.makeSid());
|
||||
this.setState({uid: uid});
|
||||
}
|
||||
return sid;
|
||||
}
|
||||
|
||||
async updateSID() {
|
||||
if (this.makeSid() !== '') {
|
||||
let uid = await CardConv.convertSID(this.makeSid());
|
||||
this.setState({uid: uid});
|
||||
}
|
||||
}
|
||||
|
||||
saveCard() {
|
||||
let sid = this.makeSid();
|
||||
|
||||
if (sid === '') {
|
||||
this.setState({sidError: true});
|
||||
return;
|
||||
}
|
||||
|
||||
saveCard(){
|
||||
let sid = this.makeSid();
|
||||
if (typeof this.state.update === 'function') {
|
||||
this.state.update(
|
||||
this.state.name,
|
||||
sid,
|
||||
this.state.index,
|
||||
this.state.image,
|
||||
this.props.navigation,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if(sid === ''){
|
||||
this.setState({sidError: true});
|
||||
return ;
|
||||
}
|
||||
setRandomSid() {
|
||||
function randomHex4Byte() {
|
||||
let hexString = Math.min(
|
||||
Math.floor(Math.random() * 65536),
|
||||
65535,
|
||||
).toString(16);
|
||||
|
||||
if(typeof this.state.update === 'function'){
|
||||
this.state.update(this.state.name, sid, this.state.index, this.state.image, this.props.navigation);
|
||||
}
|
||||
if (hexString.length < 4) {
|
||||
hexString = '0'.repeat(4 - hexString.length) + hexString;
|
||||
}
|
||||
|
||||
return hexString.toUpperCase();
|
||||
}
|
||||
|
||||
setRandomSid(){
|
||||
function randomHex4Byte(){
|
||||
let hexString = Math.min(Math.floor(Math.random() * 65536), 65535).toString(16);
|
||||
this.setState(
|
||||
{sid2: randomHex4Byte(), sid3: randomHex4Byte(), sid4: randomHex4Byte()},
|
||||
() => this.updateSID(),
|
||||
);
|
||||
}
|
||||
|
||||
if(hexString.length < 4)
|
||||
hexString = '0'.repeat(4 - hexString.length) + hexString;
|
||||
selectPhoto() {
|
||||
ImagePicker.openPicker({
|
||||
cropping: true,
|
||||
width: 856,
|
||||
height: 540,
|
||||
mediaType: 'photo',
|
||||
}).then(res => {
|
||||
if (res && res.path) {
|
||||
this.setState({image: res.path});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return hexString.toUpperCase();
|
||||
}
|
||||
render() {
|
||||
return (
|
||||
<SafeAreaView style={{flex: 1, paddingTop: StatusBar.currentHeight}}>
|
||||
<StatusBar
|
||||
barStyle="dark-content"
|
||||
translucent={true}
|
||||
backgroundColor={'#ffffff'}
|
||||
/>
|
||||
<KeyboardAvoidingView style={{flex: 1}}>
|
||||
<View
|
||||
style={{
|
||||
height: 48,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: '#ffffff',
|
||||
}}>
|
||||
<View
|
||||
style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 17,
|
||||
fontWeight: 'bold',
|
||||
textAlignVertical: 'center',
|
||||
}}>
|
||||
{this.state.mode === 'add'
|
||||
? i18n.t('header_add')
|
||||
: i18n.t('header_edit')}
|
||||
</Text>
|
||||
|
||||
this.setState({sid2: randomHex4Byte(), sid3: randomHex4Byte(), sid4: randomHex4Byte()}, () => this.updateSID());
|
||||
}
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
right: 16,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
onPress={() => this.saveCard()}>
|
||||
<Icon name="save" size={26} color={'rgba(0,0,0,0.7)'} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
<ScrollView style={{flex: 1, paddingHorizontal: 24, paddingTop: 16}}>
|
||||
<ETextInput
|
||||
title={i18n.t('edit_name')}
|
||||
value={this.state.name}
|
||||
onChangeText={text => this.setState({name: text})}
|
||||
ref={ref => (this.nameInput = ref)}
|
||||
/>
|
||||
<TouchableOpacity onPress={() => this.selectPhoto()}>
|
||||
<ETextInput
|
||||
style={{marginTop: 24}}
|
||||
title={i18n.t('edit_background')}
|
||||
value={
|
||||
this.state.image
|
||||
? i18n.t('edit_background_selected')
|
||||
: i18n.t('edit_background_empty')
|
||||
}
|
||||
editable={false}
|
||||
/>
|
||||
</TouchableOpacity>
|
||||
|
||||
selectPhoto(){
|
||||
ImagePicker.openPicker({
|
||||
cropping: true,
|
||||
width: 856,
|
||||
height: 540,
|
||||
mediaType: 'photo',
|
||||
}).then(res => {
|
||||
if(res && res.path){
|
||||
this.setState({image: res.path,});
|
||||
}
|
||||
});
|
||||
}
|
||||
<View style={{marginTop: 24, flexDirection: 'row'}}>
|
||||
<ETextInput
|
||||
title={'SID'}
|
||||
value={'02FE'}
|
||||
onChangeText={text => this.setState({sid: text})}
|
||||
style={{flex: 1}}
|
||||
editable={false}
|
||||
error={this.state.sidError}
|
||||
textStyle={{textAlign: 'center'}}
|
||||
titleStyle={
|
||||
this.state.sidError !== true &&
|
||||
this.state.sidFocus && {color: '#03A9F4'}
|
||||
}
|
||||
/>
|
||||
<Text
|
||||
style={{
|
||||
width: 20,
|
||||
marginTop: 24,
|
||||
alignSelf: 'center',
|
||||
textAlign: 'center',
|
||||
color: '#9E9E9E',
|
||||
fontSize: 14,
|
||||
}}>
|
||||
-
|
||||
</Text>
|
||||
<ETextInput
|
||||
textStyle={{textAlign: 'center'}}
|
||||
value={this.state.sid2}
|
||||
onChangeText={text => {
|
||||
this.setState({sid2: text}, () => this.updateSID());
|
||||
if (text.length === 4) {
|
||||
this.sid3Input.focus();
|
||||
}
|
||||
}}
|
||||
style={{flex: 1}}
|
||||
maxLength={4}
|
||||
error={this.state.sidError}
|
||||
onFocus={() => this.setState({sidFocus: true})}
|
||||
onBlur={() => this.setState({sidFocus: false})}
|
||||
autoCapitalize={'characters'}
|
||||
ref={ref => (this.sid2Input = ref)}
|
||||
editable={false}
|
||||
/>
|
||||
<Text
|
||||
style={{
|
||||
width: 20,
|
||||
marginTop: 24,
|
||||
alignSelf: 'center',
|
||||
textAlign: 'center',
|
||||
color: '#9E9E9E',
|
||||
fontSize: 14,
|
||||
}}>
|
||||
-
|
||||
</Text>
|
||||
<ETextInput
|
||||
textStyle={{textAlign: 'center'}}
|
||||
value={this.state.sid3}
|
||||
onChangeText={text => {
|
||||
this.setState({sid3: text}, () => this.updateSID());
|
||||
if (text.length === 4) {
|
||||
this.sid4Input.focus();
|
||||
}
|
||||
}}
|
||||
style={{flex: 1}}
|
||||
maxLength={4}
|
||||
error={this.state.sidError}
|
||||
onFocus={() => this.setState({sidFocus: true})}
|
||||
onBlur={() => this.setState({sidFocus: false})}
|
||||
autoCapitalize={'characters'}
|
||||
ref={ref => (this.sid3Input = ref)}
|
||||
editable={false}
|
||||
/>
|
||||
<Text
|
||||
style={{
|
||||
width: 20,
|
||||
marginTop: 24,
|
||||
alignSelf: 'center',
|
||||
textAlign: 'center',
|
||||
color: '#9E9E9E',
|
||||
fontSize: 14,
|
||||
}}>
|
||||
-
|
||||
</Text>
|
||||
<ETextInput
|
||||
textStyle={{textAlign: 'center'}}
|
||||
value={this.state.sid4}
|
||||
onChangeText={text => {
|
||||
this.setState({sid4: text}, () => this.updateSID());
|
||||
this.updateSID();
|
||||
}}
|
||||
style={{flex: 1}}
|
||||
error={this.state.sidError}
|
||||
maxLength={4}
|
||||
onFocus={() => this.setState({sidFocus: true})}
|
||||
onBlur={() => this.setState({sidFocus: false})}
|
||||
autoCapitalize={'characters'}
|
||||
ref={ref => (this.sid4Input = ref)}
|
||||
editable={false}
|
||||
/>
|
||||
</View>
|
||||
<Text
|
||||
style={{
|
||||
marginTop: 8,
|
||||
fontSize: 14,
|
||||
letterSpacing: -0.4,
|
||||
color: this.state.sidError ? '#F44336' : '#9E9E9E',
|
||||
}}>
|
||||
{i18n.t('edit_sid_notice')}
|
||||
</Text>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
marginTop: 24,
|
||||
height: 48,
|
||||
backgroundColor: '#03A9F4',
|
||||
borderRadius: 8,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
onPress={() => this.setRandomSid()}>
|
||||
<Text style={{fontSize: 17, color: '#ffffff', fontWeight: '500'}}>
|
||||
{i18n.t('edit_random')}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
render() {
|
||||
return (
|
||||
<SafeAreaView style={{flex: 1, paddingTop: StatusBar.currentHeight}}>
|
||||
<StatusBar
|
||||
barStyle='dark-content'
|
||||
translucent={true}
|
||||
backgroundColor={'#ffffff'}
|
||||
/>
|
||||
<KeyboardAvoidingView style={{flex: 1,}}>
|
||||
<View style={{
|
||||
height: 48,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: '#ffffff'
|
||||
}}>
|
||||
<View style={{flex: 1, alignItems: 'center',
|
||||
justifyContent: 'center',}}>
|
||||
<Text style={{
|
||||
fontSize: 17,
|
||||
fontWeight: 'bold',
|
||||
textAlignVertical: 'center',
|
||||
}}>
|
||||
{this.state.mode === 'add' ? i18n.t('header_add') : i18n.t('header_edit')}
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 14,
|
||||
color: '#9E9E9E',
|
||||
marginTop: 20,
|
||||
fontWeight: 'bold',
|
||||
}}>
|
||||
{i18n.t('edit_preview')}
|
||||
</Text>
|
||||
<CardPreview
|
||||
name={this.state.name}
|
||||
uid={this.state.uid}
|
||||
image={this.state.image}
|
||||
cardHeight={this.state.cardHeight ?? 0}
|
||||
/>
|
||||
|
||||
<TouchableOpacity style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
right: 16,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}} onPress={() => this.saveCard()}
|
||||
>
|
||||
<Icon name='save' size={26} color={'rgba(0,0,0,0.7)'}/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
<ScrollView style={{flex: 1, paddingHorizontal: 24, paddingTop: 16,}}>
|
||||
<ETextInput title={i18n.t('edit_name')} value={this.state.name} onChangeText={text => this.setState({name: text})} ref={ref => this.nameInput = ref}/>
|
||||
<TouchableOpacity onPress={() => this.selectPhoto()}>
|
||||
<ETextInput style={{marginTop: 24,}} title={i18n.t('edit_background')} value={this.state.image ? i18n.t('edit_background_selected') : i18n.t('edit_background_empty')} editable={false}/>
|
||||
</TouchableOpacity>
|
||||
|
||||
<View style={{marginTop: 24, flexDirection: 'row'}}>
|
||||
<ETextInput title={'SID'} value={'02FE'} onChangeText={text => this.setState({sid: text})}
|
||||
style={{flex: 1,}}
|
||||
editable={false}
|
||||
error={this.state.sidError}
|
||||
textStyle={{textAlign:'center',}}
|
||||
titleStyle={this.state.sidError !== true && this.state.sidFocus && {color: '#03A9F4'}}
|
||||
/>
|
||||
<Text style={{width: 20, marginTop: 24, alignSelf: 'center', textAlign:'center', color: '#9E9E9E', fontSize: 14,}}>-</Text>
|
||||
<ETextInput
|
||||
textStyle={{textAlign:'center',}}
|
||||
value={this.state.sid2}
|
||||
onChangeText={text => {this.setState({sid2: text}, () => this.updateSID()); if(text.length === 4) this.sid3Input.focus(); }}
|
||||
style={{flex: 1,}}
|
||||
maxLength={4}
|
||||
error={this.state.sidError}
|
||||
onFocus={() => this.setState({sidFocus: true})}
|
||||
onBlur={() => this.setState({sidFocus: false})}
|
||||
autoCapitalize={'characters'}
|
||||
ref={ref => this.sid2Input = ref}
|
||||
editable={false}
|
||||
/>
|
||||
<Text style={{width: 20, marginTop: 24, alignSelf: 'center', textAlign:'center', color: '#9E9E9E', fontSize: 14,}}>-</Text>
|
||||
<ETextInput
|
||||
textStyle={{textAlign:'center',}}
|
||||
value={this.state.sid3}
|
||||
onChangeText={text => {this.setState({sid3: text}, () => this.updateSID()); if(text.length === 4) this.sid4Input.focus();}}
|
||||
style={{flex: 1,}}
|
||||
maxLength={4}
|
||||
error={this.state.sidError}
|
||||
onFocus={() => this.setState({sidFocus: true})}
|
||||
onBlur={() => this.setState({sidFocus: false})}
|
||||
autoCapitalize={'characters'}
|
||||
ref={ref => this.sid3Input = ref}
|
||||
editable={false}
|
||||
/>
|
||||
<Text style={{width: 20, marginTop: 24, alignSelf: 'center', textAlign:'center', color: '#9E9E9E', fontSize: 14,}}>-</Text>
|
||||
<ETextInput
|
||||
textStyle={{textAlign:'center',}}
|
||||
value={this.state.sid4}
|
||||
onChangeText={text => {this.setState({sid4: text}, () => this.updateSID()); this.updateSID();}}
|
||||
style={{flex: 1,}}
|
||||
error={this.state.sidError}
|
||||
maxLength={4}
|
||||
onFocus={() => this.setState({sidFocus: true})}
|
||||
onBlur={() => this.setState({sidFocus: false})}
|
||||
autoCapitalize={'characters'}
|
||||
ref={ref => this.sid4Input = ref}
|
||||
editable={false}
|
||||
/>
|
||||
</View>
|
||||
<Text style={{marginTop: 8, fontSize: 14, letterSpacing: -0.4, color: this.state.sidError ? '#F44336' : '#9E9E9E'}}>
|
||||
{i18n.t('edit_sid_notice')}
|
||||
</Text>
|
||||
<TouchableOpacity style={{marginTop: 24, height: 48, backgroundColor: '#03A9F4', borderRadius:8, alignItems:'center', justifyContent:'center',}}
|
||||
onPress={() => this.setRandomSid()}
|
||||
>
|
||||
<Text style={{fontSize: 17, color: '#ffffff', fontWeight: '500'}}>{i18n.t('edit_random')}</Text>
|
||||
</TouchableOpacity>
|
||||
|
||||
<Text style={{fontSize: 14, color: '#9E9E9E', marginTop: 20, fontWeight: 'bold'}}>{i18n.t('edit_preview')}</Text>
|
||||
<CardPreview name={this.state.name} uid={this.state.uid} image={this.state.image} cardHeight={this.state.cardHeight ?? 0}/>
|
||||
|
||||
<View style={{height: 50}}/>
|
||||
</ScrollView>
|
||||
</KeyboardAvoidingView>
|
||||
</SafeAreaView>
|
||||
)
|
||||
}
|
||||
<View style={{height: 50}} />
|
||||
</ScrollView>
|
||||
</KeyboardAvoidingView>
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default CardEditScreen;
|
||||
|
@ -1,17 +1,17 @@
|
||||
import React from 'react';
|
||||
import {
|
||||
View,
|
||||
Text,
|
||||
StatusBar,
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
Dimensions,
|
||||
ImageBackground,
|
||||
findNodeHandle,
|
||||
Alert,
|
||||
StyleSheet,
|
||||
Image,
|
||||
View,
|
||||
Text,
|
||||
StatusBar,
|
||||
SafeAreaView,
|
||||
ScrollView,
|
||||
TouchableOpacity,
|
||||
Dimensions,
|
||||
ImageBackground,
|
||||
findNodeHandle,
|
||||
Alert,
|
||||
StyleSheet,
|
||||
Image,
|
||||
} from 'react-native';
|
||||
import update from 'react-addons-update';
|
||||
import Hcef from '../module/Hcef';
|
||||
@ -20,293 +20,397 @@ import AsyncStorage from '@react-native-community/async-storage';
|
||||
import Icon from 'react-native-vector-icons/MaterialIcons';
|
||||
import i18n from 'i18n-js';
|
||||
|
||||
|
||||
const RNFS = require('react-native-fs');
|
||||
|
||||
class Card extends React.Component {
|
||||
async onPress() {
|
||||
this.props.onPress(this.props.card, this.props.index);
|
||||
async onPress() {
|
||||
this.props.onPress(this.props.card, this.props.index);
|
||||
}
|
||||
|
||||
async disable() {
|
||||
if (typeof this.props.disableCallback === 'function') {
|
||||
this.props.disableCallback(this.props.card, this.props.index);
|
||||
}
|
||||
}
|
||||
|
||||
async disable(){
|
||||
if(typeof this.props.disableCallback === 'function')
|
||||
this.props.disableCallback(this.props.card, this.props.index);
|
||||
}
|
||||
render() {
|
||||
let cardContent = (
|
||||
<View
|
||||
style={{flex: 1, backgroundColor: 'rgba(0,0,0,0.3)', borderRadius: 8}}>
|
||||
<View style={{flex: 1}}>
|
||||
<TouchableOpacity style={{flex: 1}} onPress={this.onPress.bind(this)}>
|
||||
<Text
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 20,
|
||||
left: 20,
|
||||
fontSize: 17,
|
||||
fontWeight: 'bold',
|
||||
color: '#ffffff',
|
||||
}}>
|
||||
{this.props.card.name}
|
||||
</Text>
|
||||
|
||||
render() {
|
||||
let cardContent = (
|
||||
<View style={{flex: 1, backgroundColor:'rgba(0,0,0,0.3)', borderRadius:8}}>
|
||||
<View style={{flex: 1,}}>
|
||||
<TouchableOpacity style={{flex: 1}} onPress={this.onPress.bind(this)}>
|
||||
<Text style={{position: 'absolute', top: 20, left: 20, fontSize: 17, fontWeight:'bold', color:'#ffffff'}}>
|
||||
{this.props.card.name}
|
||||
</Text>
|
||||
|
||||
<View style={{flex: 1, justifyContent:'center', paddingTop: 20,}}>
|
||||
<Text style={{paddingTop: 0, textAlign: 'center', alignSelf: 'center', color: '#E0E0E0', fontSize: 14 }}>
|
||||
{this.props.card.uid.substr(0,4)+'-'+this.props.card.uid.substr(4,4)+'-'+this.props.card.uid.substr(8,4)+'-'+this.props.card.uid.substr(12,4)}
|
||||
</Text>
|
||||
<Text style={{paddingTop: 8, textAlign: 'center', alignSelf: 'center', fontSize: 24, color:'#FAFAFA', fontWeight: '500', letterSpacing:-0.5}}>
|
||||
{this.props.card.enabled ? i18n.t('card_touch_to_disable') : i18n.t('card_touch_to_enable')}
|
||||
</Text>
|
||||
</View>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={{height: 1, backgroundColor: '#FAFAFA'}}/>
|
||||
<View style={{height: 48, flexDirection: 'row'}}>
|
||||
<TouchableOpacity style={{
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}} onPress={() => this.props.navigation.navigate('CardEditScreen', {name: this.props.card.name, sid: this.props.card.sid, image: this.props.card.image, index: this.props.index, update: this.props.update})}>
|
||||
<Text style={{fontSize: 14, color:'#FAFAFA'}}>{i18n.t('card_edit')}</Text>
|
||||
</TouchableOpacity>
|
||||
<View style={{width: 1, backgroundColor: '#FAFAFA'}}/>
|
||||
<TouchableOpacity style={{
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}} onPress={() => this.props.delete(this.props.index)}>
|
||||
<Text style={{fontSize: 14, color:'#ffffff'}}>{i18n.t('card_delete')}</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={{flex: 1, justifyContent: 'center', paddingTop: 20}}>
|
||||
<Text
|
||||
style={{
|
||||
paddingTop: 0,
|
||||
textAlign: 'center',
|
||||
alignSelf: 'center',
|
||||
color: '#E0E0E0',
|
||||
fontSize: 14,
|
||||
}}>
|
||||
{this.props.card.uid.substr(0, 4) +
|
||||
'-' +
|
||||
this.props.card.uid.substr(4, 4) +
|
||||
'-' +
|
||||
this.props.card.uid.substr(8, 4) +
|
||||
'-' +
|
||||
this.props.card.uid.substr(12, 4)}
|
||||
</Text>
|
||||
<Text
|
||||
style={{
|
||||
paddingTop: 8,
|
||||
textAlign: 'center',
|
||||
alignSelf: 'center',
|
||||
fontSize: 24,
|
||||
color: '#FAFAFA',
|
||||
fontWeight: '500',
|
||||
letterSpacing: -0.5,
|
||||
}}>
|
||||
{this.props.card.enabled
|
||||
? i18n.t('card_touch_to_disable')
|
||||
: i18n.t('card_touch_to_enable')}
|
||||
</Text>
|
||||
</View>
|
||||
);
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
<View style={{height: 1, backgroundColor: '#FAFAFA'}} />
|
||||
<View style={{height: 48, flexDirection: 'row'}}>
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
onPress={() =>
|
||||
this.props.navigation.navigate('CardEditScreen', {
|
||||
name: this.props.card.name,
|
||||
sid: this.props.card.sid,
|
||||
image: this.props.card.image,
|
||||
index: this.props.index,
|
||||
update: this.props.update,
|
||||
})
|
||||
}>
|
||||
<Text style={{fontSize: 14, color: '#FAFAFA'}}>
|
||||
{i18n.t('card_edit')}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
<View style={{width: 1, backgroundColor: '#FAFAFA'}} />
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
flex: 1,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
onPress={() => this.props.delete(this.props.index)}>
|
||||
<Text style={{fontSize: 14, color: '#ffffff'}}>
|
||||
{i18n.t('card_delete')}
|
||||
</Text>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
);
|
||||
|
||||
return (
|
||||
<View style={[{
|
||||
return (
|
||||
<View
|
||||
style={[
|
||||
{
|
||||
borderRadius: 8,
|
||||
height: this.props.cardHeight,
|
||||
marginTop: 24,
|
||||
marginHorizontal: 24,
|
||||
justifyContent: 'center',
|
||||
},]}>
|
||||
{this.props.card.image ? (
|
||||
<ImageBackground
|
||||
source={{uri: this.props.card.image}}
|
||||
style={{
|
||||
flex: 1,
|
||||
resizeMode:'contain',
|
||||
}}
|
||||
blurRadius={2}
|
||||
borderRadius={8}>
|
||||
{cardContent}
|
||||
</ImageBackground>
|
||||
) : (
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
resizeMode:'contain',
|
||||
backgroundColor: '#03A9F4',
|
||||
}}
|
||||
blurRadius={2}
|
||||
borderRadius={8}>
|
||||
{cardContent}
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
},
|
||||
]}>
|
||||
{this.props.card.image ? (
|
||||
<ImageBackground
|
||||
source={{uri: this.props.card.image}}
|
||||
style={{
|
||||
flex: 1,
|
||||
resizeMode: 'contain',
|
||||
}}
|
||||
blurRadius={2}
|
||||
borderRadius={8}>
|
||||
{cardContent}
|
||||
</ImageBackground>
|
||||
) : (
|
||||
<View
|
||||
style={{
|
||||
flex: 1,
|
||||
resizeMode: 'contain',
|
||||
backgroundColor: '#03A9F4',
|
||||
}}
|
||||
blurRadius={2}
|
||||
borderRadius={8}>
|
||||
{cardContent}
|
||||
</View>
|
||||
)}
|
||||
</View>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
class MainScreen extends React.Component {
|
||||
state = {
|
||||
cards: [],
|
||||
cardHeight: 1,
|
||||
support: false,
|
||||
};
|
||||
state = {
|
||||
cards: [],
|
||||
cardHeight: 1,
|
||||
support: false,
|
||||
};
|
||||
|
||||
async loadCards(){
|
||||
let cardsJson = await AsyncStorage.getItem('cards');
|
||||
this.setState({cards: cardsJson ? JSON.parse(cardsJson) : []});
|
||||
async loadCards() {
|
||||
let cardsJson = await AsyncStorage.getItem('cards');
|
||||
this.setState({cards: cardsJson ? JSON.parse(cardsJson) : []});
|
||||
}
|
||||
|
||||
componentDidMount() {
|
||||
this.prevCard = null;
|
||||
this.prevIndex = -1;
|
||||
this.loadCards();
|
||||
|
||||
if (Hcef.support !== true) {
|
||||
Alert.alert(
|
||||
i18n.t('alert_not_support_title'),
|
||||
i18n.t('alert_not_support_content'),
|
||||
[{text: i18n.t('alert_not_support_yes')}],
|
||||
);
|
||||
} else if (Hcef.enabled !== true) {
|
||||
Alert.alert(i18n.t('alert_nfc_title'), i18n.t('alert_nfc_content'), [
|
||||
{text: i18n.t('alert_nfc_yes')},
|
||||
]);
|
||||
}
|
||||
|
||||
componentDidMount(){
|
||||
this.prevCard = null;
|
||||
this.prevIndex = -1;
|
||||
this.loadCards();
|
||||
if (Hcef.support && Hcef.enabled) {
|
||||
Hcef.disableService(); // 카드를 활성화하지 않았는데도 카드가 에뮬되는 이슈 방지
|
||||
}
|
||||
|
||||
if(Hcef.support !== true){
|
||||
Alert.alert(i18n.t('alert_not_support_title'), i18n.t('alert_not_support_content'),
|
||||
[{text: i18n.t('alert_not_support_yes')}]);
|
||||
}
|
||||
else if(Hcef.enabled !== true){
|
||||
Alert.alert(i18n.t('alert_nfc_title'), i18n.t('alert_nfc_content'),
|
||||
[{text: i18n.t('alert_nfc_yes')}]);
|
||||
}
|
||||
let {height, width} = Dimensions.get('window');
|
||||
|
||||
if(Hcef.support && Hcef.enabled){
|
||||
Hcef.disableService(); // 카드를 활성화하지 않았는데도 카드가 에뮬되는 이슈 방지
|
||||
}
|
||||
this.setState({
|
||||
cardHeight: ((width - 48) * 53.98) / 85.6,
|
||||
});
|
||||
}
|
||||
|
||||
let {height, width} = (Dimensions.get('window'));
|
||||
async switch(card, index) {
|
||||
if (!Hcef.support || !Hcef.enabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (card.enabled === true) {
|
||||
this.disable(card, index);
|
||||
} else {
|
||||
this.enable(card, index);
|
||||
}
|
||||
}
|
||||
|
||||
async enable(card, index) {
|
||||
if (this.prevCard && this.prevCard.enabled) {
|
||||
await this.disable(this.prevCard, this.prevIndex);
|
||||
}
|
||||
|
||||
let ret = false;
|
||||
let ret2 = false;
|
||||
|
||||
ret = await Hcef.setSID(card.sid);
|
||||
if (ret) {
|
||||
ret2 = await Hcef.enableService();
|
||||
}
|
||||
|
||||
if (ret && ret2) {
|
||||
this.prevCard = card;
|
||||
this.prevCard.enabled = true;
|
||||
this.prevIndex = index;
|
||||
this.setState({
|
||||
cards: update(this.state.cards, {[index]: {enabled: {$set: true}}}),
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
async disable(card, index) {
|
||||
if (card.enabled) {
|
||||
let ret = await Hcef.disableService();
|
||||
if (ret) {
|
||||
card.enabled = false;
|
||||
this.setState({
|
||||
cardHeight: (width - 48) * 53.98 / 85.60
|
||||
cards: update(this.state.cards, {[index]: {enabled: {$set: false}}}),
|
||||
});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
async cardListUpdate(name, sid, index, image, navigation) {
|
||||
let uid = await CardConv.convertSID(sid);
|
||||
let internalPath = '';
|
||||
|
||||
if (image !== '') {
|
||||
internalPath = RNFS.DocumentDirectoryPath + '/' + new Date().valueOf();
|
||||
|
||||
if (image.startsWith('file://')) {
|
||||
image = image.replace('file://', '');
|
||||
}
|
||||
|
||||
await RNFS.copyFile(image, internalPath);
|
||||
|
||||
internalPath = 'file://' + internalPath;
|
||||
}
|
||||
|
||||
async switch(card, index){
|
||||
if(!Hcef.support || !Hcef.enabled) return;
|
||||
|
||||
if(card.enabled === true)
|
||||
this.disable(card, index);
|
||||
else
|
||||
this.enable(card, index);
|
||||
if (index === null) {
|
||||
this.setState(
|
||||
{
|
||||
cards: update(this.state.cards, {
|
||||
$push: [{name: name, sid: sid, uid: uid, image: internalPath}],
|
||||
}),
|
||||
},
|
||||
async () => {
|
||||
await AsyncStorage.setItem('cards', JSON.stringify(this.state.cards));
|
||||
},
|
||||
);
|
||||
} else {
|
||||
this.setState(
|
||||
{
|
||||
cards: update(this.state.cards, {
|
||||
[index]: {
|
||||
name: {$set: name},
|
||||
sid: {$set: sid},
|
||||
uid: {$set: uid},
|
||||
image: {$set: internalPath},
|
||||
},
|
||||
}),
|
||||
},
|
||||
async () => {
|
||||
await AsyncStorage.setItem('cards', JSON.stringify(this.state.cards));
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
async enable(card, index){
|
||||
if(this.prevCard && this.prevCard.enabled) {
|
||||
await this.disable(this.prevCard, this.prevIndex);
|
||||
}
|
||||
Alert.alert('', i18n.t('alert_save_content'), [
|
||||
{
|
||||
text: i18n.t('alert_save_yes'),
|
||||
onPress: () => {
|
||||
navigation.goBack();
|
||||
},
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
let ret = false;
|
||||
let ret2 = false;
|
||||
cardListDelete(index) {
|
||||
Alert.alert(i18n.t('alert_delete_title'), i18n.t('alert_delete_content'), [
|
||||
{text: i18n.t('alert_delete_no')},
|
||||
{
|
||||
text: i18n.t('alert_delete_yes'),
|
||||
onPress: () => {
|
||||
if (this.state.cards[index].image !== '') {
|
||||
RNFS.unlink(this.state.cards[index].image);
|
||||
}
|
||||
this.setState(
|
||||
{
|
||||
cards: update(this.state.cards, {
|
||||
$splice: [[index, 1]],
|
||||
}),
|
||||
},
|
||||
async () => {
|
||||
await AsyncStorage.setItem(
|
||||
'cards',
|
||||
JSON.stringify(this.state.cards),
|
||||
);
|
||||
},
|
||||
);
|
||||
},
|
||||
},
|
||||
]);
|
||||
}
|
||||
|
||||
ret = await Hcef.setSID(card.sid);
|
||||
if(ret){
|
||||
ret2 = await Hcef.enableService();
|
||||
}
|
||||
render() {
|
||||
let cardWidget = [];
|
||||
|
||||
if(ret && ret2){
|
||||
this.prevCard = card;
|
||||
this.prevCard.enabled = true;
|
||||
this.prevIndex = index;
|
||||
this.setState({cards: update(this.state.cards, { [index]: { enabled: { $set: true } }})});
|
||||
}
|
||||
}
|
||||
this.state.cards.forEach((card, index) => {
|
||||
cardWidget.push(
|
||||
<Card
|
||||
card={card}
|
||||
index={index}
|
||||
onPress={(card, index) => this.switch(card, index)}
|
||||
cardHeight={this.state.cardHeight}
|
||||
disableCallback={(card, index) => this.disable(card, index)}
|
||||
update={(name, sid, index, image, navigation) =>
|
||||
this.cardListUpdate(name, sid, index, image, navigation)
|
||||
}
|
||||
delete={index => this.cardListDelete(index)}
|
||||
navigation={this.props.navigation}
|
||||
/>,
|
||||
);
|
||||
});
|
||||
|
||||
async disable(card, index){
|
||||
if(card.enabled){
|
||||
let ret = await Hcef.disableService();
|
||||
if(ret){
|
||||
card.enabled = false;
|
||||
this.setState({cards: update(this.state.cards, { [index]: { enabled: { $set: false } }})});
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
return (
|
||||
<SafeAreaView style={{flex: 1, paddingTop: StatusBar.currentHeight}}>
|
||||
<StatusBar
|
||||
barStyle="dark-content"
|
||||
translucent={true}
|
||||
backgroundColor={'#ffffff'}
|
||||
/>
|
||||
<View
|
||||
style={{
|
||||
height: 48,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: '#ffffff',
|
||||
}}>
|
||||
<View
|
||||
style={{flex: 1, alignItems: 'center', justifyContent: 'center'}}>
|
||||
<Text
|
||||
style={{
|
||||
fontSize: 17,
|
||||
fontWeight: 'bold',
|
||||
textAlignVertical: 'center',
|
||||
}}>
|
||||
{i18n.t('header_home')}
|
||||
</Text>
|
||||
|
||||
async cardListUpdate(name, sid, index, image, navigation){
|
||||
let uid = await CardConv.convertSID(sid);
|
||||
let internalPath = '';
|
||||
<TouchableOpacity
|
||||
style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
right: 12,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}}
|
||||
onPress={() =>
|
||||
this.props.navigation.navigate('CardEditScreen', {
|
||||
update: (name, sid, index, image, navigation) =>
|
||||
this.cardListUpdate(name, sid, index, image, navigation),
|
||||
})
|
||||
}>
|
||||
<Icon name="add" size={26} color={'rgba(0,0,0,0.7)'} />
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
if(image !== ''){
|
||||
internalPath = RNFS.DocumentDirectoryPath + '/' + new Date().valueOf();
|
||||
|
||||
if(image.startsWith('file://')){
|
||||
image = image.replace("file://",'');
|
||||
}
|
||||
|
||||
await RNFS.copyFile(image, internalPath);
|
||||
|
||||
internalPath = 'file://' + internalPath;
|
||||
}
|
||||
|
||||
if(index === null){
|
||||
this.setState({cards: update(this.state.cards, { $push: [{name: name, sid: sid, uid: uid, image: internalPath}]})},
|
||||
async () => {
|
||||
await AsyncStorage.setItem('cards', JSON.stringify(this.state.cards));
|
||||
});
|
||||
}
|
||||
else{
|
||||
this.setState({cards: update(this.state.cards, { [index]: { name: {$set: name}, sid: {$set: sid}, uid: {$set: uid}, image: {$set: internalPath} }})},
|
||||
async () =>{
|
||||
await AsyncStorage.setItem('cards', JSON.stringify(this.state.cards));
|
||||
});
|
||||
}
|
||||
|
||||
Alert.alert("", i18n.t('alert_save_content'),
|
||||
[{text: i18n.t('alert_save_yes'), onPress: () => {navigation.goBack();}}]);
|
||||
}
|
||||
|
||||
cardListDelete(index){
|
||||
Alert.alert(i18n.t('alert_delete_title'),i18n.t('alert_delete_content')
|
||||
, [
|
||||
{text: i18n.t('alert_delete_no')},
|
||||
{text: i18n.t('alert_delete_yes'), onPress: () => {
|
||||
if(this.state.cards[index].image !== '' ){
|
||||
RNFS.unlink(this.state.cards[index].image);
|
||||
}
|
||||
this.setState({
|
||||
cards: update(this.state.cards, {
|
||||
$splice: [[index, 1]]
|
||||
})
|
||||
}, async () => {
|
||||
await AsyncStorage.setItem('cards', JSON.stringify(this.state.cards));
|
||||
}
|
||||
);
|
||||
}}]
|
||||
);
|
||||
}
|
||||
|
||||
render() {
|
||||
let cardWidget = [];
|
||||
|
||||
this.state.cards.forEach((card, index) => {
|
||||
cardWidget.push(
|
||||
<Card card={card} index={index}
|
||||
onPress={(card, index) => this.switch(card, index)} cardHeight={this.state.cardHeight}
|
||||
disableCallback={(card, index) => this.disable(card, index)}
|
||||
update={(name, sid, index, image, navigation) => this.cardListUpdate(name, sid, index, image, navigation)}
|
||||
delete={(index) => this.cardListDelete(index)}
|
||||
navigation={this.props.navigation}
|
||||
/>);
|
||||
});
|
||||
|
||||
return (
|
||||
<SafeAreaView style={{flex: 1, paddingTop: StatusBar.currentHeight}}>
|
||||
<StatusBar
|
||||
barStyle='dark-content'
|
||||
translucent={true}
|
||||
backgroundColor={'#ffffff'}
|
||||
/>
|
||||
<View style={{
|
||||
height: 48,
|
||||
flexDirection: 'row',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
backgroundColor: '#ffffff',
|
||||
}}>
|
||||
<View style={{flex: 1, alignItems: 'center',
|
||||
justifyContent: 'center',}}>
|
||||
<Text style={{
|
||||
fontSize: 17,
|
||||
fontWeight: 'bold',
|
||||
textAlignVertical: 'center',
|
||||
}}>
|
||||
{i18n.t('header_home')}
|
||||
</Text>
|
||||
|
||||
<TouchableOpacity style={{
|
||||
position: 'absolute',
|
||||
top: 0,
|
||||
bottom: 0,
|
||||
right: 12,
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
}} onPress={() => this.props.navigation.navigate('CardEditScreen',{ update:(name, sid, index, image, navigation) => this.cardListUpdate(name, sid, index, image, navigation)})}
|
||||
>
|
||||
<Icon name='add' size={26} color={'rgba(0,0,0,0.7)'}/>
|
||||
</TouchableOpacity>
|
||||
</View>
|
||||
</View>
|
||||
|
||||
{this.state.cards && this.state.cards.length > 0 ? (
|
||||
<ScrollView style={{flex: 1,}}>
|
||||
{cardWidget}
|
||||
</ScrollView>
|
||||
) : (
|
||||
<View style={{flex:1, justifyContent: 'center', alignItems:'center'}}>
|
||||
<Text style={{fontSize: 17, color: '#9E9E9E', }}>{i18n.t('main_empty_string')}</Text>
|
||||
</View>
|
||||
)
|
||||
}
|
||||
|
||||
</SafeAreaView>
|
||||
)
|
||||
}
|
||||
{this.state.cards && this.state.cards.length > 0 ? (
|
||||
<ScrollView style={{flex: 1}}>{cardWidget}</ScrollView>
|
||||
) : (
|
||||
<View
|
||||
style={{flex: 1, justifyContent: 'center', alignItems: 'center'}}>
|
||||
<Text style={{fontSize: 17, color: '#9E9E9E'}}>
|
||||
{i18n.t('main_empty_string')}
|
||||
</Text>
|
||||
</View>
|
||||
)}
|
||||
</SafeAreaView>
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
export default MainScreen;
|
||||
|
Loading…
x
Reference in New Issue
Block a user