Browse Source

Further theme switching improvements

Arnaud Vergnet 4 years ago
parent
commit
f282a1dd84

+ 2
- 1
src/components/Custom/CustomAgenda.js View File

45
     }
45
     }
46
 
46
 
47
     render() {
47
     render() {
48
-        if (this.props.theme.colors.text === "#ffffff") // We are in light mode
48
+        // Completely recreate the component on theme change to force theme reload
49
+        if (this.props.theme.dark)
49
             return (
50
             return (
50
                 <View style={{flex: 1}}>
51
                 <View style={{flex: 1}}>
51
                     {this.getAgenda()}
52
                     {this.getAgenda()}

+ 44
- 0
src/components/Custom/CustomHTML.js View File

1
+import * as React from 'react';
2
+import {View} from "react-native";
3
+import {withTheme} from 'react-native-paper';
4
+import HTML from "react-native-render-html";
5
+import {Linking} from "expo";
6
+
7
+type Props = {
8
+    theme: Object,
9
+    html: string,
10
+}
11
+
12
+/**
13
+ * Abstraction layer for Agenda component, using custom configuration
14
+ */
15
+class CustomHTML extends React.Component<Props> {
16
+
17
+    openWebLink = (event, link) => {
18
+        Linking.openURL(link).catch((err) => console.error('Error opening link', err));
19
+    };
20
+
21
+    getHTML() {
22
+        // Surround description with div to allow text styling if the description is not html
23
+        return <HTML html={"<div>" + this.props.html + "</div>"}
24
+                     tagsStyles={{
25
+                         p: {color: this.props.theme.colors.text},
26
+                         div: {color: this.props.theme.colors.text}
27
+                     }}
28
+                     onLinkPress={this.openWebLink}/>;
29
+    }
30
+
31
+    render() {
32
+        // Completely recreate the component on theme change to force theme reload
33
+        if (this.props.theme.dark)
34
+            return (
35
+                <View style={{flex: 1}}>
36
+                    {this.getHTML()}
37
+                </View>
38
+            );
39
+        else
40
+            return this.getHTML();
41
+    }
42
+}
43
+
44
+export default withTheme(CustomHTML);

+ 4
- 10
src/components/Home/PreviewEventDashboardItem.js View File

2
 
2
 
3
 import * as React from 'react';
3
 import * as React from 'react';
4
 import {StyleSheet, View} from "react-native";
4
 import {StyleSheet, View} from "react-native";
5
-import HTML from "react-native-render-html";
6
 import i18n from "i18n-js";
5
 import i18n from "i18n-js";
7
-import {Avatar, Button, Card, withTheme} from 'react-native-paper';
6
+import {Avatar, Button, Card} from 'react-native-paper';
8
 import {getFormattedEventTime, isDescriptionEmpty} from "../../utils/Planning";
7
 import {getFormattedEventTime, isDescriptionEmpty} from "../../utils/Planning";
8
+import CustomHTML from "../Custom/CustomHTML";
9
 
9
 
10
 /**
10
 /**
11
  * Component used to display an event preview if an event is available
11
  * Component used to display an event preview if an event is available
14
  * @return {*}
14
  * @return {*}
15
  */
15
  */
16
 function PreviewEventDashboardItem(props) {
16
 function PreviewEventDashboardItem(props) {
17
-    const {colors} = props.theme;
18
     const isEmpty = props.event === undefined
17
     const isEmpty = props.event === undefined
19
         ? true
18
         ? true
20
         : isDescriptionEmpty(props.event['description']);
19
         : isDescriptionEmpty(props.event['description']);
43
                     />}
42
                     />}
44
                 {!isEmpty ?
43
                 {!isEmpty ?
45
                     <Card.Content style={styles.content}>
44
                     <Card.Content style={styles.content}>
46
-                        <HTML html={"<div>" + props.event['description'] + "</div>"}
47
-                              tagsStyles={{
48
-                                  p: {color: colors.text,},
49
-                                  div: {color: colors.text},
50
-                              }}/>
51
-
45
+                        <CustomHTML html={props.event['description']}/>
52
                     </Card.Content> : null}
46
                     </Card.Content> : null}
53
 
47
 
54
                 <Card.Actions style={styles.actions}>
48
                 <Card.Actions style={styles.actions}>
82
     }
76
     }
83
 });
77
 });
84
 
78
 
85
-export default withTheme(PreviewEventDashboardItem);
79
+export default PreviewEventDashboardItem;

+ 2
- 12
src/screens/Amicale/Clubs/ClubDisplayScreen.js View File

2
 
2
 
3
 import * as React from 'react';
3
 import * as React from 'react';
4
 import {ScrollView, View} from 'react-native';
4
 import {ScrollView, View} from 'react-native';
5
-import HTML from "react-native-render-html";
6
-import {Linking} from "expo";
7
 import {Avatar, Card, Chip, Paragraph, withTheme} from 'react-native-paper';
5
 import {Avatar, Card, Chip, Paragraph, withTheme} from 'react-native-paper';
8
 import ImageModal from 'react-native-image-modal';
6
 import ImageModal from 'react-native-image-modal';
9
 import i18n from "i18n-js";
7
 import i18n from "i18n-js";
10
 import AuthenticatedScreen from "../../../components/Amicale/AuthenticatedScreen";
8
 import AuthenticatedScreen from "../../../components/Amicale/AuthenticatedScreen";
9
+import CustomHTML from "../../../components/Custom/CustomHTML";
11
 
10
 
12
 type Props = {
11
 type Props = {
13
     navigation: Object,
12
     navigation: Object,
18
     imageModalVisible: boolean,
17
     imageModalVisible: boolean,
19
 };
18
 };
20
 
19
 
21
-function openWebLink(event, link) {
22
-    Linking.openURL(link).catch((err) => console.error('Error opening link', err));
23
-}
24
-
25
 /**
20
 /**
26
  * Class defining a club event information page.
21
  * Class defining a club event information page.
27
  * If called with data and categories navigation parameters, will use those to display the data.
22
  * If called with data and categories navigation parameters, will use those to display the data.
146
                 {data.description !== null ?
141
                 {data.description !== null ?
147
                     // Surround description with div to allow text styling if the description is not html
142
                     // Surround description with div to allow text styling if the description is not html
148
                     <Card.Content>
143
                     <Card.Content>
149
-                        <HTML html={"<div>" + data.description + "</div>"}
150
-                              tagsStyles={{
151
-                                  p: {color: this.colors.text,},
152
-                                  div: {color: this.colors.text}
153
-                              }}
154
-                              onLinkPress={openWebLink}/>
144
+                        <CustomHTML html={data.description}/>
155
                     </Card.Content>
145
                     </Card.Content>
156
                     : <View/>}
146
                     : <View/>}
157
                 {this.getManagersRender(data.responsibles)}
147
                 {this.getManagersRender(data.responsibles)}

+ 13
- 26
src/screens/Amicale/ProfileScreen.js View File

24
         dialogVisible: false,
24
         dialogVisible: false,
25
     };
25
     };
26
 
26
 
27
-    colors: Object;
28
-
29
     data: Object;
27
     data: Object;
30
 
28
 
31
     flatListData: Array<Object>;
29
     flatListData: Array<Object>;
32
 
30
 
33
-    constructor(props) {
34
-        super(props);
35
-        this.colors = props.theme.colors;
31
+    constructor() {
32
+        super();
36
         this.flatListData = [
33
         this.flatListData = [
37
             {id: '0'},
34
             {id: '0'},
38
             {id: '1'},
35
             {id: '1'},
105
     }
102
     }
106
 
103
 
107
     /**
104
     /**
108
-     * Gets the color depending on the value.
109
-     *
110
-     * @param field The field to get the color for
111
-     * @return {*}
112
-     */
113
-    getFieldColor(field: ?string) {
114
-        return this.isFieldAvailable(field)
115
-            ? this.colors.text
116
-            : this.colors.textDisabled;
117
-    }
118
-
119
-    /**
120
      * Gets a list item showing personal information
105
      * Gets a list item showing personal information
121
      *
106
      *
122
      * @param field The field to display
107
      * @param field The field to display
124
      * @return {*}
109
      * @return {*}
125
      */
110
      */
126
     getPersonalListItem(field: ?string, icon: string) {
111
     getPersonalListItem(field: ?string, icon: string) {
112
+        let title = this.isFieldAvailable(field) ? this.getFieldValue(field) : ':(';
113
+        let subtitle = this.isFieldAvailable(field) ? '' : this.getFieldValue(field);
127
         return (
114
         return (
128
             <List.Item
115
             <List.Item
129
-                title={this.getFieldValue(field)}
116
+                title={title}
117
+                description={subtitle}
130
                 left={props => <List.Icon
118
                 left={props => <List.Icon
131
                     {...props}
119
                     {...props}
132
                     icon={icon}
120
                     icon={icon}
133
-                    color={this.getFieldColor(field)}
121
+                    color={this.isFieldAvailable(field) ? undefined : this.props.theme.colors.textDisabled}
134
                 />}
122
                 />}
135
-                titleStyle={{color: this.getFieldColor(field)}}
136
             />
123
             />
137
         );
124
         );
138
     }
125
     }
151
                     left={(props) => <Avatar.Icon
138
                     left={(props) => <Avatar.Icon
152
                         {...props}
139
                         {...props}
153
                         icon="account"
140
                         icon="account"
154
-                        color={this.colors.primary}
141
+                        color={this.props.theme.colors.primary}
155
                         style={styles.icon}
142
                         style={styles.icon}
156
                     />}
143
                     />}
157
                 />
144
                 />
169
                         <Button
156
                         <Button
170
                             icon="account-edit"
157
                             icon="account-edit"
171
                             mode="contained"
158
                             mode="contained"
172
-                            onPress={() => openBrowser(this.data.link, this.colors.primary)}
159
+                            onPress={() => openBrowser(this.data.link, this.props.theme.colors.primary)}
173
                             style={styles.editButton}>
160
                             style={styles.editButton}>
174
                             {i18n.t("profileScreen.editInformation")}
161
                             {i18n.t("profileScreen.editInformation")}
175
                         </Button>
162
                         </Button>
193
                     left={(props) => <Avatar.Icon
180
                     left={(props) => <Avatar.Icon
194
                         {...props}
181
                         {...props}
195
                         icon="account-group"
182
                         icon="account-group"
196
-                        color={this.colors.primary}
183
+                        color={this.props.theme.colors.primary}
197
                         style={styles.icon}
184
                         style={styles.icon}
198
                     />}
185
                     />}
199
                 />
186
                 />
219
                     left={(props) => <Avatar.Icon
206
                     left={(props) => <Avatar.Icon
220
                         {...props}
207
                         {...props}
221
                         icon="credit-card"
208
                         icon="credit-card"
222
-                        color={this.colors.primary}
209
+                        color={this.props.theme.colors.primary}
223
                         style={styles.icon}
210
                         style={styles.icon}
224
                     />}
211
                     />}
225
                 />
212
                 />
243
                 title={state ? i18n.t("profileScreen.membershipPayed") : i18n.t("profileScreen.membershipNotPayed")}
230
                 title={state ? i18n.t("profileScreen.membershipPayed") : i18n.t("profileScreen.membershipNotPayed")}
244
                 left={props => <List.Icon
231
                 left={props => <List.Icon
245
                     {...props}
232
                     {...props}
246
-                    color={state ? this.colors.success : this.colors.danger}
233
+                    color={state ? this.props.theme.colors.success : this.props.theme.colors.danger}
247
                     icon={state ? 'check' : 'close'}
234
                     icon={state ? 'check' : 'close'}
248
                 />}
235
                 />}
249
             />
236
             />
270
         let icon = (props) => <List.Icon {...props} icon="chevron-right"/>;
257
         let icon = (props) => <List.Icon {...props} icon="chevron-right"/>;
271
         if (item.is_manager) {
258
         if (item.is_manager) {
272
             description = i18n.t("profileScreen.isManager");
259
             description = i18n.t("profileScreen.isManager");
273
-            icon = (props) => <List.Icon {...props} icon="star" color={this.colors.primary}/>;
260
+            icon = (props) => <List.Icon {...props} icon="star" color={this.props.theme.colors.primary}/>;
274
         }
261
         }
275
         return <List.Item
262
         return <List.Item
276
             title={item.name}
263
             title={item.name}

+ 3
- 14
src/screens/Planning/PlanningDisplayScreen.js View File

2
 
2
 
3
 import * as React from 'react';
3
 import * as React from 'react';
4
 import {ScrollView, View} from 'react-native';
4
 import {ScrollView, View} from 'react-native';
5
-import HTML from "react-native-render-html";
6
-import {Linking} from "expo";
7
 import {getDateOnlyString, getFormattedEventTime} from '../../utils/Planning';
5
 import {getDateOnlyString, getFormattedEventTime} from '../../utils/Planning';
8
 import {Card, withTheme} from 'react-native-paper';
6
 import {Card, withTheme} from 'react-native-paper';
9
 import DateManager from "../../managers/DateManager";
7
 import DateManager from "../../managers/DateManager";
11
 import BasicLoadingScreen from "../../components/Custom/BasicLoadingScreen";
9
 import BasicLoadingScreen from "../../components/Custom/BasicLoadingScreen";
12
 import {apiRequest} from "../../utils/WebData";
10
 import {apiRequest} from "../../utils/WebData";
13
 import ErrorView from "../../components/Custom/ErrorView";
11
 import ErrorView from "../../components/Custom/ErrorView";
12
+import CustomHTML from "../../components/Custom/CustomHTML";
14
 
13
 
15
 type Props = {
14
 type Props = {
16
     navigation: Object,
15
     navigation: Object,
21
     loading: boolean
20
     loading: boolean
22
 };
21
 };
23
 
22
 
24
-function openWebLink(event, link) {
25
-    Linking.openURL(link).catch((err) => console.error('Error opening link', err));
26
-}
27
-
28
 const CLUB_INFO_PATH = "event/info";
23
 const CLUB_INFO_PATH = "event/info";
29
 
24
 
30
 /**
25
 /**
111
                     : <View/>}
106
                     : <View/>}
112
 
107
 
113
                 {this.displayData.description !== null ?
108
                 {this.displayData.description !== null ?
114
-                    // Surround description with div to allow text styling if the description is not html
115
                     <Card.Content>
109
                     <Card.Content>
116
-                        <HTML html={"<div>" + this.displayData.description + "</div>"}
117
-                              tagsStyles={{
118
-                                  p: {color: this.colors.text,},
119
-                                  div: {color: this.colors.text}
120
-                              }}
121
-                              onLinkPress={openWebLink}/>
110
+                        <CustomHTML html={this.displayData.description}/>
122
                     </Card.Content>
111
                     </Card.Content>
123
                     : <View/>}
112
                     : <View/>}
124
             </ScrollView>
113
             </ScrollView>
131
         else if (this.errorCode === 0)
120
         else if (this.errorCode === 0)
132
             return this.getContent();
121
             return this.getContent();
133
         else
122
         else
134
-            return <ErrorView {...this.props} errorCode={this.errorCode}   onRefresh={this.fetchData}/>;
123
+            return <ErrorView {...this.props} errorCode={this.errorCode} onRefresh={this.fetchData}/>;
135
     }
124
     }
136
 }
125
 }
137
 
126
 

Loading…
Cancel
Save