Improved dashboard event item

This commit is contained in:
keplyx 2020-03-09 19:00:12 +01:00
parent 9ec986574f
commit c720600afd
5 changed files with 168 additions and 214 deletions

View file

@ -1,190 +0,0 @@
// @flow
import * as React from 'react';
import {MaterialCommunityIcons} from "@expo/vector-icons";
import {View} from "react-native";
import ThemeManager from "../utils/ThemeManager";
import HTML from "react-native-render-html";
import {LinearGradient} from "expo-linear-gradient";
import i18n from "i18n-js";
import {Avatar, Card, Text} from 'react-native-paper';
type Props = {
isAvailable: boolean,
icon: string,
color: string,
title: string,
subtitle: React.Node,
clickAction: Function,
isSquare: boolean,
isSquareLeft: boolean,
displayEvent: ?Object,
}
export default class DashboardItem extends React.Component<Props> {
static defaultProps = {
isSquare: false,
isSquareLeft: true,
displayEvent: undefined,
};
getIcon: Function;
constructor() {
super();
this.getIcon = this.getIcon.bind(this);
}
/**
* Convert the date string given by in the event list json to a date object
* @param dateString
* @return {Date}
*/
stringToDate(dateString: ?string): ?Date {
let date = new Date();
if (dateString === undefined || dateString === null)
date = undefined;
else if (dateString.split(' ').length > 1) {
let timeStr = dateString.split(' ')[1];
date.setHours(parseInt(timeStr.split(':')[0]), parseInt(timeStr.split(':')[1]), 0);
} else
date = undefined;
return date;
}
padStr(i: number) {
return (i < 10) ? "0" + i : "" + i;
}
getFormattedEventTime(event: Object): string {
let formattedStr = '';
let startDate = this.stringToDate(event['date_begin']);
let endDate = this.stringToDate(event['date_end']);
if (startDate !== undefined && startDate !== null && endDate !== undefined && endDate !== null)
formattedStr = this.padStr(startDate.getHours()) + ':' + this.padStr(startDate.getMinutes()) +
' - ' + this.padStr(endDate.getHours()) + ':' + this.padStr(endDate.getMinutes());
else if (startDate !== undefined && startDate !== null)
formattedStr = this.padStr(startDate.getHours()) + ':' + this.padStr(startDate.getMinutes());
return formattedStr
}
getEventPreviewContainer() {
if (this.props.displayEvent !== undefined && this.props.displayEvent !== null) {
const hasImage = this.props.displayEvent['logo'] !== '' && this.props.displayEvent['logo'] !== null;
const getImage = () => <Avatar.Image
source={{uri: this.props.displayEvent['logo']}}
size={60}
style={{backgroundColor: 'transparent'}}/>;
return (
<Card style={{marginBottom: 10}}>
{hasImage ?
<Card.Title
title={this.props.displayEvent['title']}
subtitle={this.getFormattedEventTime(this.props.displayEvent)}
left={getImage}
/> :
<Card.Title
title={this.props.displayEvent['title']}
subtitle={this.getFormattedEventTime(this.props.displayEvent)}
/>}
<View>
<Card.Content style={{
height: this.props.displayEvent['description'].length > 70 ? 100 : 50,
overflow: 'hidden',
}}>
<HTML html={"<div>" + this.props.displayEvent['description'] + "</div>"}
tagsStyles={{
p: {
color: ThemeManager.getCurrentThemeVariables().text,
},
div: {color: ThemeManager.getCurrentThemeVariables().text},
}}/>
</Card.Content>
<LinearGradient
colors={[
// Fix for ios gradient: transparent color must match final color
ThemeManager.getNightMode() ? 'rgba(42,42,42,0)' : 'rgba(255,255,255,0)',
ThemeManager.getCurrentThemeVariables().card
]}
start={{x: 0, y: 0}}
end={{x: 0, y: 0.6}}
// end={[0, 0.6]}
style={{
position: 'absolute',
width: '100%',
height: 65,
bottom: -5,
}}>
<View style={{
marginLeft: 'auto',
marginTop: 'auto',
flexDirection: 'row'
}}>
<Text style={{
marginTop: 'auto',
marginBottom: 'auto',
padding: 0,
}}>
{i18n.t("homeScreen.dashboard.seeMore")}
</Text>
<MaterialCommunityIcons
name={'chevron-right'}
size={26}
color={ThemeManager.getCurrentThemeVariables().text}/>
</View>
</LinearGradient>
</View>
</Card>
);
} else
return <View/>
}
getIcon() {
return (
<Avatar.Icon
icon={this.props.icon}
color={this.props.isAvailable ? this.props.color : ThemeManager.getCurrentThemeVariables().textDisabled}
size={60}
style={{backgroundColor: 'transparent'}}/>
);
}
render() {
// console.log("rendering DashboardItem " + this.props.title);
let marginRight = 10;
if (this.props.isSquare) {
if (this.props.isSquareLeft)
marginRight = '4%';
else
marginRight = 0
}
const color = this.props.isAvailable ?
ThemeManager.getCurrentThemeVariables().text :
ThemeManager.getCurrentThemeVariables().textDisabled;
return (
<Card
style={{
width: this.props.isSquare ? '48%' : 'auto',
marginLeft: this.props.isSquare ? 0 : 10,
marginRight: marginRight,
marginTop: 10,
overflow: 'hidden',
}}
onPress={this.props.clickAction}>
<Card.Title
title={this.props.title}
titleStyle={{color: color}}
subtitle={this.props.subtitle}
subtitleStyle={{color: color}}
left={this.getIcon}
/>
<Card.Content>
{this.getEventPreviewContainer()}
</Card.Content>
</Card>
);
}
}

View file

@ -0,0 +1,49 @@
// @flow
import * as React from 'react';
import {Avatar, Card, withTheme} from 'react-native-paper';
function getIcon(icon, color) {
return (
<Avatar.Icon
icon={icon}
color={color}
size={60}
style={{backgroundColor: 'transparent'}}/>
);
}
function EventDashBoardItem(props) {
const {colors} = props.theme;
const iconColor = props.isAvailable ?
colors.planningColor :
colors.textDisabled;
const textColor = props.isAvailable ?
colors.text :
colors.textDisabled;
return (
<Card
style={{
width: 'auto',
marginLeft: 10,
marginRight: 10,
marginTop: 10,
overflow: 'hidden',
}}
onPress={props.clickAction}>
<Card.Title
title={props.title}
titleStyle={{color: textColor}}
subtitle={props.subtitle}
subtitleStyle={{color: textColor}}
left={() => getIcon(props.icon, iconColor)}
/>
<Card.Content>
{props.children}
</Card.Content>
</Card>
);
}
export default withTheme(EventDashBoardItem);

View file

@ -0,0 +1,65 @@
// @flow
import * as React from 'react';
import {MaterialCommunityIcons} from "@expo/vector-icons";
import {View} from "react-native";
import HTML from "react-native-render-html";
import i18n from "i18n-js";
import {Avatar, Card, Text, withTheme, Button} from 'react-native-paper';
import PlanningEventManager from "../utils/PlanningEventManager";
function PreviewEventDashboardItem(props) {
const {colors} = props.theme;
if (props.event !== undefined && props.event !== null) {
const hasImage = props.event['logo'] !== '' && props.event['logo'] !== null;
const getImage = () => <Avatar.Image
source={{uri: props.event['logo']}}
size={50}
style={{backgroundColor: 'transparent'}}/>;
return (
<Card
style={{marginBottom: 10}}
onPress={props.clickAction}
elevation={3}
>
{hasImage ?
<Card.Title
title={props.event['title']}
subtitle={PlanningEventManager.getFormattedEventTime(props.event)}
left={getImage}
/> :
<Card.Title
title={props.event['title']}
subtitle={PlanningEventManager.getFormattedEventTime(props.event)}
/>}
<Card.Content style={{
height: props.event['description'].length > 70 ? 100 : 50,
overflow: 'hidden',
}}>
<HTML html={"<div>" + props.event['description'] + "</div>"}
tagsStyles={{
p: {color: colors.text,},
div: {color: colors.text},
}}/>
</Card.Content>
<Card.Actions style={{
marginLeft: 'auto',
marginTop: 'auto',
flexDirection: 'row'
}}>
<Button
icon={'chevron-right'}
>
{i18n.t("homeScreen.dashboard.seeMore")}
</Button>
</Card.Actions>
</Card>
);
} else
return <View/>
}
export default withTheme(PreviewEventDashboardItem);

View file

@ -5,12 +5,13 @@ import {TouchableOpacity, View} from 'react-native';
import i18n from "i18n-js"; import i18n from "i18n-js";
import Autolink from 'react-native-autolink'; import Autolink from 'react-native-autolink';
import ThemeManager from "../utils/ThemeManager"; import ThemeManager from "../utils/ThemeManager";
import DashboardItem from "../components/DashboardItem"; import DashboardItem from "../components/EventDashboardItem";
import * as WebBrowser from 'expo-web-browser'; import * as WebBrowser from 'expo-web-browser';
import WebSectionList from "../components/WebSectionList"; import WebSectionList from "../components/WebSectionList";
import {Avatar, Button, Card, Text} from 'react-native-paper'; import {Avatar, Button, Card, Text} from 'react-native-paper';
import FeedItem from "../components/FeedItem"; import FeedItem from "../components/FeedItem";
import SquareDashboardItem from "../components/SquareDashboardItem"; import SquareDashboardItem from "../components/SquareDashboardItem";
import PreviewEventDashboardItem from "../components/PreviewEventDashboardItem";
// import DATA from "../dashboard_data.json"; // import DATA from "../dashboard_data.json";
@ -24,8 +25,6 @@ const SECTIONS_ID = [
const REFRESH_TIME = 1000 * 20; // Refresh every 20 seconds const REFRESH_TIME = 1000 * 20; // Refresh every 20 seconds
const CARD_BORDER_RADIUS = 10;
type Props = { type Props = {
navigation: Object, navigation: Object,
} }
@ -288,17 +287,8 @@ export default class HomeScreen extends React.Component<Props> {
} }
clickAction(isAvailable: boolean, displayEvent: Object) {
if (isAvailable)
this.props.navigation.navigate('PlanningDisplayScreen', {data: displayEvent});
else
this.props.navigation.navigate('Planning');
};
getDashboardEventItem(content: Array<Object>) { getDashboardEventItem(content: Array<Object>) {
let icon = 'calendar-range'; let icon = 'calendar-range';
let color = ThemeManager.getCurrentThemeVariables().planningColor;
let title = i18n.t('homeScreen.dashboard.todayEventsTitle'); let title = i18n.t('homeScreen.dashboard.todayEventsTitle');
let subtitle; let subtitle;
let futureEvents = this.getFutureEvents(content); let futureEvents = this.getFutureEvents(content);
@ -319,17 +309,23 @@ export default class HomeScreen extends React.Component<Props> {
subtitle = i18n.t('homeScreen.dashboard.todayEventsSubtitleNA'); subtitle = i18n.t('homeScreen.dashboard.todayEventsSubtitleNA');
let displayEvent = this.getDisplayEvent(futureEvents); let displayEvent = this.getDisplayEvent(futureEvents);
const clickAction = this.clickAction.bind(this, isAvailable, displayEvent); const clickContainerAction = () => this.props.navigation.navigate('Planning');
const clickPreviewAction = () => this.props.navigation.navigate('PlanningDisplayScreen', {data: displayEvent});;
return ( return (
<DashboardItem <DashboardItem
{...this.props}
subtitle={subtitle} subtitle={subtitle}
color={color}
icon={icon} icon={icon}
clickAction={clickAction} clickAction={clickContainerAction}
title={title} title={title}
isAvailable={isAvailable} isAvailable={isAvailable}
displayEvent={displayEvent} >
/> <PreviewEventDashboardItem
{...this.props}
event={displayEvent}
clickAction={clickPreviewAction}
/>
</DashboardItem>
); );
} }

View file

@ -3,9 +3,9 @@ export default class PlanningEventManager {
static isEventBefore(event1: Object, event2: Object) { static isEventBefore(event1: Object, event2: Object) {
let date1 = new Date(); let date1 = new Date();
let date2 = new Date(); let date2 = new Date();
let timeArray = this.getEventStartTime(event1).split(":"); let timeArray = PlanningEventManager.getEventStartTime(event1).split(":");
date1.setHours(parseInt(timeArray[0]), parseInt(timeArray[1])); date1.setHours(parseInt(timeArray[0]), parseInt(timeArray[1]));
timeArray = this.getEventStartTime(event2).split(":"); timeArray = PlanningEventManager.getEventStartTime(event2).split(":");
date2.setHours(parseInt(timeArray[0]), parseInt(timeArray[1])); date2.setHours(parseInt(timeArray[0]), parseInt(timeArray[1]));
return date1 < date2; return date1 < date2;
} }
@ -16,27 +16,61 @@ export default class PlanningEventManager {
static getEventStartTime(event: Object) { static getEventStartTime(event: Object) {
if (event !== undefined && Object.keys(event).length > 0 && event.date_begin !== null) if (event !== undefined && Object.keys(event).length > 0 && event.date_begin !== null)
return this.formatTime(event.date_begin.split(" ")[1]); return PlanningEventManager.formatTime(event.date_begin.split(" ")[1]);
else else
return ""; return "";
} }
static getEventEndTime(event: Object) { static getEventEndTime(event: Object) {
if (event !== undefined && Object.keys(event).length > 0 && event.date_end !== null) if (event !== undefined && Object.keys(event).length > 0 && event.date_end !== null)
return this.formatTime(event.date_end.split(" ")[1]); return PlanningEventManager.formatTime(event.date_end.split(" ")[1]);
else else
return ""; return "";
} }
static getFormattedTime(event: Object) { static getFormattedTime(event: Object) {
if (this.getEventEndTime(event) !== "") if (PlanningEventManager.getEventEndTime(event) !== "")
return this.getEventStartTime(event) + " - " + this.getEventEndTime(event); return PlanningEventManager.getEventStartTime(event) + " - " + PlanningEventManager.getEventEndTime(event);
else else
return this.getEventStartTime(event); return PlanningEventManager.getEventStartTime(event);
} }
static formatTime(time: string) { static formatTime(time: string) {
let array = time.split(':'); let array = time.split(':');
return array[0] + ':' + array[1]; return array[0] + ':' + array[1];
} }
/**
* Convert the date string given by in the event list json to a date object
* @param dateString
* @return {Date}
*/
static stringToDate(dateString: ?string): ?Date {
let date = new Date();
if (dateString === undefined || dateString === null)
date = undefined;
else if (dateString.split(' ').length > 1) {
let timeStr = dateString.split(' ')[1];
date.setHours(parseInt(timeStr.split(':')[0]), parseInt(timeStr.split(':')[1]), 0);
} else
date = undefined;
return date;
}
static padStr(i: number) {
return (i < 10) ? "0" + i : "" + i;
}
static getFormattedEventTime(event: Object): string {
let formattedStr = '';
let startDate = PlanningEventManager.stringToDate(event['date_begin']);
let endDate = PlanningEventManager.stringToDate(event['date_end']);
if (startDate !== undefined && startDate !== null && endDate !== undefined && endDate !== null)
formattedStr = PlanningEventManager.padStr(startDate.getHours()) + ':' + PlanningEventManager.padStr(startDate.getMinutes()) +
' - ' + PlanningEventManager.padStr(endDate.getHours()) + ':' + PlanningEventManager.padStr(endDate.getMinutes());
else if (startDate !== undefined && startDate !== null)
formattedStr = PlanningEventManager.padStr(startDate.getHours()) + ':' + PlanningEventManager.padStr(startDate.getMinutes());
return formattedStr
}
} }