forked from vergnet/application-amicale
Moved planning event display in own screen
This commit is contained in:
parent
c904cdb235
commit
128b398aac
9 changed files with 195 additions and 171 deletions
|
@ -14,6 +14,7 @@ import {NavigationActions} from "react-navigation";
|
|||
type Props = {
|
||||
navigation: Object,
|
||||
headerTitle: string,
|
||||
headerSubtitle: string,
|
||||
headerRightButton: React.Node,
|
||||
children: React.Node,
|
||||
hasTabs: boolean,
|
||||
|
@ -37,6 +38,7 @@ export default class BaseContainer extends React.Component<Props, State> {
|
|||
hasSideMenu: true,
|
||||
enableRotation: false,
|
||||
hideHeaderOnLandscape: false,
|
||||
headerSubtitle: '',
|
||||
};
|
||||
willBlurSubscription: function;
|
||||
willFocusSubscription: function;
|
||||
|
@ -96,7 +98,9 @@ export default class BaseContainer extends React.Component<Props, State> {
|
|||
<Container>
|
||||
{this.state.isHeaderVisible ?
|
||||
<CustomHeader
|
||||
navigation={this.props.navigation} title={this.props.headerTitle}
|
||||
navigation={this.props.navigation}
|
||||
title={this.props.headerTitle}
|
||||
subtitle={this.props.headerSubtitle}
|
||||
leftButton={
|
||||
<Touchable
|
||||
style={{padding: 6}}
|
||||
|
|
|
@ -1,14 +1,14 @@
|
|||
// @flow
|
||||
|
||||
import * as React from "react";
|
||||
import {Body, Header, Input, Item, Left, Right, Title} from "native-base";
|
||||
import {Body, Header, Input, Item, Left, Right, Subtitle, Title} from "native-base";
|
||||
import {Platform, StyleSheet, View} from "react-native";
|
||||
import {getStatusBarHeight} from "react-native-status-bar-height";
|
||||
import Touchable from 'react-native-platform-touchable';
|
||||
import ThemeManager from "../utils/ThemeManager";
|
||||
import CustomMaterialIcon from "./CustomMaterialIcon";
|
||||
import i18n from "i18n-js";
|
||||
import { NavigationActions } from 'react-navigation';
|
||||
import {NavigationActions} from 'react-navigation';
|
||||
|
||||
type Props = {
|
||||
hasBackButton: boolean,
|
||||
|
@ -18,6 +18,7 @@ type Props = {
|
|||
leftButton: React.Node,
|
||||
rightButton: React.Node,
|
||||
title: string,
|
||||
subtitle: string,
|
||||
navigation: Object,
|
||||
hasTabs: boolean,
|
||||
};
|
||||
|
@ -38,6 +39,7 @@ export default class CustomHeader extends React.Component<Props> {
|
|||
searchCallback: () => null,
|
||||
shouldFocusSearchBar: false,
|
||||
title: '',
|
||||
subtitle: '',
|
||||
leftButton: <View/>,
|
||||
rightButton: <View/>,
|
||||
hasTabs: false,
|
||||
|
@ -52,6 +54,7 @@ export default class CustomHeader extends React.Component<Props> {
|
|||
|
||||
getSearchBar() {
|
||||
return (
|
||||
<Body>
|
||||
<Item
|
||||
style={{
|
||||
width: '100%',
|
||||
|
@ -66,9 +69,24 @@ export default class CustomHeader extends React.Component<Props> {
|
|||
placeholderTextColor={ThemeManager.getCurrentThemeVariables().toolbarPlaceholderColor}
|
||||
onChangeText={(text) => this.props.searchCallback(text)}/>
|
||||
</Item>
|
||||
</Body>
|
||||
);
|
||||
}
|
||||
|
||||
getHeaderTitle() {
|
||||
return (
|
||||
<Body>
|
||||
<Title style={{
|
||||
color: ThemeManager.getCurrentThemeVariables().toolbarTextColor
|
||||
}}>
|
||||
{this.props.title}
|
||||
</Title>
|
||||
{this.props.subtitle !== '' ? <Subtitle>{this.props.subtitle}</Subtitle> : null}
|
||||
</Body>
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
render() {
|
||||
let button;
|
||||
// Does the app have a back button or a burger menu ?
|
||||
|
@ -93,14 +111,9 @@ export default class CustomHeader extends React.Component<Props> {
|
|||
<Left style={{flex: 0}}>
|
||||
{button}
|
||||
</Left>
|
||||
<Body>
|
||||
{this.props.hasSearchField ?
|
||||
this.getSearchBar() :
|
||||
<Title style={{
|
||||
paddingLeft: 10,
|
||||
color: ThemeManager.getCurrentThemeVariables().toolbarTextColor
|
||||
}}>{this.props.title}</Title>}
|
||||
</Body>
|
||||
this.getHeaderTitle()}
|
||||
<Right style={{flex: this.props.hasSearchField ? 0 : 1}}>
|
||||
{this.props.rightButton}
|
||||
</Right>
|
||||
|
@ -108,7 +121,6 @@ export default class CustomHeader extends React.Component<Props> {
|
|||
}
|
||||
};
|
||||
|
||||
|
||||
// Fix header in status bar on Android
|
||||
const styles = StyleSheet.create({
|
||||
header: {
|
||||
|
|
|
@ -4,6 +4,7 @@ import {createMaterialBottomTabNavigator} from "react-navigation-material-bottom
|
|||
|
||||
import HomeScreen from '../screens/HomeScreen';
|
||||
import PlanningScreen from '../screens/PlanningScreen';
|
||||
import PlanningDisplayScreen from '../screens/PlanningDisplayScreen';
|
||||
import ProxiwashScreen from '../screens/Proxiwash/ProxiwashScreen';
|
||||
import ProxiwashAboutScreen from '../screens/Proxiwash/ProxiwashAboutScreen';
|
||||
import ProximoMainScreen from '../screens/Proximo/ProximoMainScreen';
|
||||
|
@ -57,10 +58,40 @@ const ProxiwashStack = createStackNavigator({
|
|||
},
|
||||
});
|
||||
|
||||
const PlanningStack = createStackNavigator({
|
||||
PlanningScreen: {screen: PlanningScreen},
|
||||
PlanningDisplayScreen: {screen: PlanningDisplayScreen},
|
||||
},
|
||||
{
|
||||
initialRouteName: "PlanningScreen",
|
||||
mode: 'card',
|
||||
headerMode: "none",
|
||||
defaultNavigationOptions: {
|
||||
gestureEnabled: true,
|
||||
cardOverlayEnabled: true,
|
||||
...TransitionPresets.ModalPresentationIOS,
|
||||
},
|
||||
});
|
||||
|
||||
const HomeStack = createStackNavigator({
|
||||
HomeScreen: {screen: HomeScreen},
|
||||
PlanningDisplayScreen: {screen: PlanningDisplayScreen},
|
||||
},
|
||||
{
|
||||
initialRouteName: "HomeScreen",
|
||||
mode: 'card',
|
||||
headerMode: "none",
|
||||
defaultNavigationOptions: {
|
||||
gestureEnabled: true,
|
||||
cardOverlayEnabled: true,
|
||||
...TransitionPresets.ModalPresentationIOS,
|
||||
},
|
||||
});
|
||||
|
||||
function createMaterialBottomTabNavigatorWithInitialRoute(initialRoute: string) {
|
||||
return createMaterialBottomTabNavigator({
|
||||
Home: {screen: HomeScreen},
|
||||
Planning: {screen: PlanningScreen},
|
||||
Home: HomeStack,
|
||||
Planning: PlanningStack,
|
||||
Proxiwash: ProxiwashStack,
|
||||
Proximo: ProximoStack,
|
||||
Planex: {
|
||||
|
|
|
@ -310,7 +310,7 @@ export default class HomeScreen extends FetchedDataSectionList {
|
|||
</Text>;
|
||||
} else
|
||||
subtitle = i18n.t('homeScreen.dashboard.todayEventsSubtitleNA');
|
||||
let clickAction = () => this.props.navigation.navigate('Planning');
|
||||
let clickAction = () => this.props.navigation.navigate('PlanningDisplayScreen', {data: displayEvent});
|
||||
|
||||
let displayEvent = this.getDisplayEvent(futureEvents);
|
||||
|
||||
|
|
63
screens/PlanningDisplayScreen.js
Normal file
63
screens/PlanningDisplayScreen.js
Normal file
|
@ -0,0 +1,63 @@
|
|||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import {Image} from 'react-native';
|
||||
import {Container, Content, H1, H3, View} from 'native-base';
|
||||
import CustomHeader from "../components/CustomHeader";
|
||||
import ThemeManager from "../utils/ThemeManager";
|
||||
import HTML from "react-native-render-html";
|
||||
import {Linking} from "expo";
|
||||
import PlanningEventManager from '../utils/PlanningEventManager';
|
||||
import i18n from 'i18n-js';
|
||||
|
||||
type Props = {
|
||||
navigation: Object,
|
||||
};
|
||||
|
||||
function openWebLink(link) {
|
||||
Linking.openURL(link).catch((err) => console.error('Error opening link', err));
|
||||
}
|
||||
|
||||
/**
|
||||
* Class defining an about screen. This screen shows the user information about the app and it's author.
|
||||
*/
|
||||
export default class PlanningDisplayScreen extends React.Component<Props> {
|
||||
|
||||
render() {
|
||||
const nav = this.props.navigation;
|
||||
const displayData = nav.getParam('data', []);
|
||||
return (
|
||||
<Container>
|
||||
<CustomHeader
|
||||
navigation={nav}
|
||||
title={i18n.t('screens.planningDisplayScreen')}
|
||||
subtitle={PlanningEventManager.getFormattedTime(displayData)}
|
||||
hasBackButton={true}/>
|
||||
<Content padder>
|
||||
<H1>
|
||||
{displayData.title}
|
||||
</H1>
|
||||
{displayData.logo !== null ?
|
||||
<View style={{width: '100%', height: 300, marginTop: 20, marginBottom: 20}}>
|
||||
<Image style={{flex: 1, resizeMode: "contain"}}
|
||||
source={{uri: displayData.logo}}/>
|
||||
</View>
|
||||
: <View/>}
|
||||
|
||||
{displayData.description !== null ?
|
||||
// Surround description with div to allow text styling if the description is not html
|
||||
<HTML html={"<div>" + displayData.description + "</div>"}
|
||||
tagsStyles={{
|
||||
p: {
|
||||
color: ThemeManager.getCurrentThemeVariables().textColor,
|
||||
fontSize: ThemeManager.getCurrentThemeVariables().fontSizeBase
|
||||
},
|
||||
div: {color: ThemeManager.getCurrentThemeVariables().textColor}
|
||||
}}
|
||||
onLinkPress={(event, link) => openWebLink(link)}/>
|
||||
: <View/>}
|
||||
</Content>
|
||||
</Container>
|
||||
);
|
||||
}
|
||||
}
|
|
@ -1,18 +1,16 @@
|
|||
// @flow
|
||||
|
||||
import * as React from 'react';
|
||||
import {BackHandler, Image, View} from 'react-native';
|
||||
import {Button, Content, H1, H3, Text} from 'native-base';
|
||||
import {BackHandler, Image} from 'react-native';
|
||||
import {H3, Text, View} from 'native-base';
|
||||
import i18n from "i18n-js";
|
||||
import ThemeManager from "../utils/ThemeManager";
|
||||
import {Linking} from "expo";
|
||||
import BaseContainer from "../components/BaseContainer";
|
||||
import {Agenda, LocaleConfig} from 'react-native-calendars';
|
||||
import HTML from 'react-native-render-html';
|
||||
import Touchable from 'react-native-platform-touchable';
|
||||
import {Modalize} from 'react-native-modalize';
|
||||
import WebDataManager from "../utils/WebDataManager";
|
||||
import CustomMaterialIcon from "../components/CustomMaterialIcon";
|
||||
import PlanningEventManager from '../utils/PlanningEventManager';
|
||||
|
||||
LocaleConfig.locales['fr'] = {
|
||||
monthNames: ['Janvier', 'Février', 'Mars', 'Avril', 'Mai', 'Juin', 'Juillet', 'Août', 'Septembre', 'Octobre', 'Novembre', 'Décembre'],
|
||||
|
@ -28,7 +26,6 @@ type Props = {
|
|||
}
|
||||
|
||||
type State = {
|
||||
modalCurrentDisplayItem: Object,
|
||||
refreshing: boolean,
|
||||
agendaItems: Object,
|
||||
calendarShowing: boolean,
|
||||
|
@ -51,7 +48,6 @@ function openWebLink(link) {
|
|||
*/
|
||||
export default class PlanningScreen extends React.Component<Props, State> {
|
||||
|
||||
modalRef: Modalize;
|
||||
agendaRef: Agenda;
|
||||
webDataManager: WebDataManager;
|
||||
|
||||
|
@ -61,7 +57,6 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
|||
didFocusSubscription: Function;
|
||||
willBlurSubscription: Function;
|
||||
state = {
|
||||
modalCurrentDisplayItem: {},
|
||||
refreshing: false,
|
||||
agendaItems: {},
|
||||
calendarShowing: false,
|
||||
|
@ -69,7 +64,6 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
|||
|
||||
constructor(props: any) {
|
||||
super(props);
|
||||
this.modalRef = React.createRef();
|
||||
this.webDataManager = new WebDataManager(FETCH_URL);
|
||||
this.didFocusSubscription = props.navigation.addListener(
|
||||
'didFocus',
|
||||
|
@ -131,72 +125,11 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
|||
return daysOfYear;
|
||||
}
|
||||
|
||||
getModalHeader() {
|
||||
return (
|
||||
<View style={{marginBottom: 0}}>
|
||||
<Button
|
||||
onPress={() => this.modalRef.current.close()}
|
||||
style={{
|
||||
marginTop: 50,
|
||||
marginLeft: 'auto',
|
||||
}}
|
||||
transparent>
|
||||
<CustomMaterialIcon icon={'close'}/>
|
||||
</Button>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
getModalContent() {
|
||||
return (
|
||||
<View style={{
|
||||
flex: 1,
|
||||
padding: 20
|
||||
}}>
|
||||
<H1>
|
||||
{this.state.modalCurrentDisplayItem.title}
|
||||
</H1>
|
||||
<H3 style={{
|
||||
marginTop: 10,
|
||||
color: ThemeManager.getCurrentThemeVariables().listNoteColor
|
||||
}}>
|
||||
{this.getFormattedTime(this.state.modalCurrentDisplayItem)}
|
||||
</H3>
|
||||
<Content>
|
||||
{this.state.modalCurrentDisplayItem.logo !== null ?
|
||||
<View style={{width: '100%', height: 200, marginTop: 20, marginBottom: 20}}>
|
||||
<Image style={{flex: 1, resizeMode: "contain"}}
|
||||
source={{uri: this.state.modalCurrentDisplayItem.logo}}/>
|
||||
</View>
|
||||
: <View/>}
|
||||
|
||||
{this.state.modalCurrentDisplayItem.description !== null ?
|
||||
// Surround description with div to allow text styling if the description is not html
|
||||
<HTML html={"<div>" + this.state.modalCurrentDisplayItem.description + "</div>"}
|
||||
tagsStyles={{
|
||||
p: {
|
||||
color: ThemeManager.getCurrentThemeVariables().textColor,
|
||||
fontSize: ThemeManager.getCurrentThemeVariables().fontSizeBase
|
||||
},
|
||||
div: {color: ThemeManager.getCurrentThemeVariables().textColor}
|
||||
}}
|
||||
onLinkPress={(event, link) => openWebLink(link)}/>
|
||||
: <View/>}
|
||||
</Content>
|
||||
</View>
|
||||
);
|
||||
}
|
||||
|
||||
showItemDetails(item: Object) {
|
||||
this.setState({
|
||||
modalCurrentDisplayItem: item,
|
||||
});
|
||||
if (this.modalRef.current) {
|
||||
this.modalRef.current.open();
|
||||
}
|
||||
}
|
||||
|
||||
getRenderItem(item: Object) {
|
||||
let navData = {
|
||||
data: item
|
||||
};
|
||||
const nav = this.props.navigation;
|
||||
return (
|
||||
<Touchable
|
||||
style={{
|
||||
|
@ -205,7 +138,7 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
|||
marginRight: 10,
|
||||
marginTop: 17,
|
||||
}}
|
||||
onPress={() => this.showItemDetails(item)}>
|
||||
onPress={() => nav.navigate('PlanningDisplayScreen', navData)}>
|
||||
<View style={{
|
||||
padding: 10,
|
||||
flex: 1,
|
||||
|
@ -219,7 +152,7 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
|||
marginTop: 5,
|
||||
marginBottom: 10
|
||||
}}>
|
||||
{this.getFormattedTime(item)}
|
||||
{PlanningEventManager.getFormattedTime(item)}
|
||||
</Text>
|
||||
<H3 style={{marginBottom: 10}}>{item.title}</H3>
|
||||
</View>
|
||||
|
@ -296,8 +229,8 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
|||
generateEventAgenda(eventList: Array<Object>) {
|
||||
let agendaItems = this.generateEmptyCalendar();
|
||||
for (let i = 0; i < eventList.length; i++) {
|
||||
if (agendaItems[this.getEventStartDate(eventList[i])] !== undefined) {
|
||||
this.pushEventInOrder(agendaItems, eventList[i], this.getEventStartDate(eventList[i]));
|
||||
if (agendaItems[PlanningEventManager.getEventStartDate(eventList[i])] !== undefined) {
|
||||
this.pushEventInOrder(agendaItems, eventList[i], PlanningEventManager.getEventStartDate(eventList[i]));
|
||||
}
|
||||
}
|
||||
this.setState({agendaItems: agendaItems})
|
||||
|
@ -308,7 +241,7 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
|||
agendaItems[startDate].push(event);
|
||||
else {
|
||||
for (let i = 0; i < agendaItems[startDate].length; i++) {
|
||||
if (this.isEventBefore(event, agendaItems[startDate][i])) {
|
||||
if (PlanningEventManager.isEventBefore(event, agendaItems[startDate][i])) {
|
||||
agendaItems[startDate].splice(i, 0, event);
|
||||
break;
|
||||
} else if (i === agendaItems[startDate].length - 1) {
|
||||
|
@ -319,65 +252,10 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
|||
}
|
||||
}
|
||||
|
||||
isEventBefore(event1: Object, event2: Object) {
|
||||
let date1 = new Date();
|
||||
let date2 = new Date();
|
||||
let timeArray = this.getEventStartTime(event1).split(":");
|
||||
date1.setHours(parseInt(timeArray[0]), parseInt(timeArray[1]));
|
||||
timeArray = this.getEventStartTime(event2).split(":");
|
||||
date2.setHours(parseInt(timeArray[0]), parseInt(timeArray[1]));
|
||||
return date1 < date2;
|
||||
}
|
||||
|
||||
getEventStartDate(event: Object) {
|
||||
return event.date_begin.split(" ")[0];
|
||||
}
|
||||
|
||||
getEventStartTime(event: Object) {
|
||||
if (event !== undefined && Object.keys(event).length > 0 && event.date_begin !== null)
|
||||
return this.formatTime(event.date_begin.split(" ")[1]);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
getEventEndTime(event: Object) {
|
||||
if (event !== undefined && Object.keys(event).length > 0 && event.date_end !== null)
|
||||
return this.formatTime(event.date_end.split(" ")[1]);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
getFormattedTime(event: Object) {
|
||||
if (this.getEventEndTime(event) !== "")
|
||||
return this.getEventStartTime(event) + " - " + this.getEventEndTime(event);
|
||||
else
|
||||
return this.getEventStartTime(event);
|
||||
}
|
||||
|
||||
formatTime(time: string) {
|
||||
let array = time.split(':');
|
||||
return array[0] + ':' + array[1];
|
||||
}
|
||||
|
||||
onModalClosed() {
|
||||
this.setState({
|
||||
modalCurrentDisplayItem: {},
|
||||
});
|
||||
}
|
||||
|
||||
render() {
|
||||
const nav = this.props.navigation;
|
||||
return (
|
||||
<BaseContainer navigation={nav} headerTitle={i18n.t('screens.planning')}>
|
||||
<Modalize ref={this.modalRef}
|
||||
modalStyle={{
|
||||
backgroundColor: ThemeManager.getCurrentThemeVariables().containerBgColor,
|
||||
}}
|
||||
// adjustToContentHeight // Breaks when displaying full screen, half, then full again
|
||||
HeaderComponent={() => this.getModalHeader()}
|
||||
onClosed={() => this.onModalClosed()}>
|
||||
{this.getModalContent()}
|
||||
</Modalize>
|
||||
<Agenda
|
||||
// the list of items that have to be displayed in agenda. If you want to render item as empty date
|
||||
// the value of date key kas to be an empty array []. If there exists no value for date key it is
|
||||
|
@ -431,14 +309,6 @@ export default class PlanningScreen extends React.Component<Props, State> {
|
|||
agendaDayNumColor: ThemeManager.getCurrentThemeVariables().listNoteColor,
|
||||
agendaTodayColor: ThemeManager.getCurrentThemeVariables().brandPrimary,
|
||||
agendaKnobColor: ThemeManager.getCurrentThemeVariables().brandPrimary,
|
||||
// Fix for days hiding behind knob
|
||||
'stylesheet.calendar.header': {
|
||||
week: {
|
||||
marginTop: 0,
|
||||
flexDirection: 'row',
|
||||
justifyContent: 'space-between'
|
||||
}
|
||||
}
|
||||
}}
|
||||
/>
|
||||
</BaseContainer>
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
"screens": {
|
||||
"home": "Home",
|
||||
"planning": "Planning",
|
||||
"planningDisplayScreen": "Event Details",
|
||||
"proxiwash": "Proxiwash",
|
||||
"proximo": "Proximo",
|
||||
"menuSelf": "RU Menu",
|
||||
|
|
|
@ -2,6 +2,7 @@
|
|||
"screens": {
|
||||
"home": "Accueil",
|
||||
"planning": "Planning",
|
||||
"planningDisplayScreen": "Détails",
|
||||
"proxiwash": "Proxiwash",
|
||||
"proximo": "Proximo",
|
||||
"menuSelf": "Menu du RU",
|
||||
|
|
42
utils/PlanningEventManager.js
Normal file
42
utils/PlanningEventManager.js
Normal file
|
@ -0,0 +1,42 @@
|
|||
|
||||
export default class PlanningEventManager {
|
||||
static isEventBefore(event1: Object, event2: Object) {
|
||||
let date1 = new Date();
|
||||
let date2 = new Date();
|
||||
let timeArray = this.getEventStartTime(event1).split(":");
|
||||
date1.setHours(parseInt(timeArray[0]), parseInt(timeArray[1]));
|
||||
timeArray = this.getEventStartTime(event2).split(":");
|
||||
date2.setHours(parseInt(timeArray[0]), parseInt(timeArray[1]));
|
||||
return date1 < date2;
|
||||
}
|
||||
|
||||
static getEventStartDate(event: Object) {
|
||||
return event.date_begin.split(" ")[0];
|
||||
}
|
||||
|
||||
static getEventStartTime(event: Object) {
|
||||
if (event !== undefined && Object.keys(event).length > 0 && event.date_begin !== null)
|
||||
return this.formatTime(event.date_begin.split(" ")[1]);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
static getEventEndTime(event: Object) {
|
||||
if (event !== undefined && Object.keys(event).length > 0 && event.date_end !== null)
|
||||
return this.formatTime(event.date_end.split(" ")[1]);
|
||||
else
|
||||
return "";
|
||||
}
|
||||
|
||||
static getFormattedTime(event: Object) {
|
||||
if (this.getEventEndTime(event) !== "")
|
||||
return this.getEventStartTime(event) + " - " + this.getEventEndTime(event);
|
||||
else
|
||||
return this.getEventStartTime(event);
|
||||
}
|
||||
|
||||
static formatTime(time: string) {
|
||||
let array = time.split(':');
|
||||
return array[0] + ':' + array[1];
|
||||
}
|
||||
}
|
Loading…
Reference in a new issue