Browse Source

Further theme switching improvements

Arnaud Vergnet 1 year ago
parent
commit
f282a1dd84

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

@@ -45,7 +45,8 @@ class CustomAgenda extends React.Component<Props> {
45 45
     }
46 46
 
47 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 50
             return (
50 51
                 <View style={{flex: 1}}>
51 52
                     {this.getAgenda()}

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

@@ -0,0 +1,44 @@
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,10 +2,10 @@
2 2
 
3 3
 import * as React from 'react';
4 4
 import {StyleSheet, View} from "react-native";
5
-import HTML from "react-native-render-html";
6 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 7
 import {getFormattedEventTime, isDescriptionEmpty} from "../../utils/Planning";
8
+import CustomHTML from "../Custom/CustomHTML";
9 9
 
10 10
 /**
11 11
  * Component used to display an event preview if an event is available
@@ -14,7 +14,6 @@ import {getFormattedEventTime, isDescriptionEmpty} from "../../utils/Planning";
14 14
  * @return {*}
15 15
  */
16 16
 function PreviewEventDashboardItem(props) {
17
-    const {colors} = props.theme;
18 17
     const isEmpty = props.event === undefined
19 18
         ? true
20 19
         : isDescriptionEmpty(props.event['description']);
@@ -43,12 +42,7 @@ function PreviewEventDashboardItem(props) {
43 42
                     />}
44 43
                 {!isEmpty ?
45 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 46
                     </Card.Content> : null}
53 47
 
54 48
                 <Card.Actions style={styles.actions}>
@@ -82,4 +76,4 @@ const styles = StyleSheet.create({
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,12 +2,11 @@
2 2
 
3 3
 import * as React from 'react';
4 4
 import {ScrollView, View} from 'react-native';
5
-import HTML from "react-native-render-html";
6
-import {Linking} from "expo";
7 5
 import {Avatar, Card, Chip, Paragraph, withTheme} from 'react-native-paper';
8 6
 import ImageModal from 'react-native-image-modal';
9 7
 import i18n from "i18n-js";
10 8
 import AuthenticatedScreen from "../../../components/Amicale/AuthenticatedScreen";
9
+import CustomHTML from "../../../components/Custom/CustomHTML";
11 10
 
12 11
 type Props = {
13 12
     navigation: Object,
@@ -18,10 +17,6 @@ type State = {
18 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 21
  * Class defining a club event information page.
27 22
  * If called with data and categories navigation parameters, will use those to display the data.
@@ -146,12 +141,7 @@ class ClubDisplayScreen extends React.Component<Props, State> {
146 141
                 {data.description !== null ?
147 142
                     // Surround description with div to allow text styling if the description is not html
148 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 145
                     </Card.Content>
156 146
                     : <View/>}
157 147
                 {this.getManagersRender(data.responsibles)}

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

@@ -24,15 +24,12 @@ class ProfileScreen extends React.Component<Props, State> {
24 24
         dialogVisible: false,
25 25
     };
26 26
 
27
-    colors: Object;
28
-
29 27
     data: Object;
30 28
 
31 29
     flatListData: Array<Object>;
32 30
 
33
-    constructor(props) {
34
-        super(props);
35
-        this.colors = props.theme.colors;
31
+    constructor() {
32
+        super();
36 33
         this.flatListData = [
37 34
             {id: '0'},
38 35
             {id: '1'},
@@ -105,18 +102,6 @@ class ProfileScreen extends React.Component<Props, State> {
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 105
      * Gets a list item showing personal information
121 106
      *
122 107
      * @param field The field to display
@@ -124,15 +109,17 @@ class ProfileScreen extends React.Component<Props, State> {
124 109
      * @return {*}
125 110
      */
126 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 114
         return (
128 115
             <List.Item
129
-                title={this.getFieldValue(field)}
116
+                title={title}
117
+                description={subtitle}
130 118
                 left={props => <List.Icon
131 119
                     {...props}
132 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,7 +138,7 @@ class ProfileScreen extends React.Component<Props, State> {
151 138
                     left={(props) => <Avatar.Icon
152 139
                         {...props}
153 140
                         icon="account"
154
-                        color={this.colors.primary}
141
+                        color={this.props.theme.colors.primary}
155 142
                         style={styles.icon}
156 143
                     />}
157 144
                 />
@@ -169,7 +156,7 @@ class ProfileScreen extends React.Component<Props, State> {
169 156
                         <Button
170 157
                             icon="account-edit"
171 158
                             mode="contained"
172
-                            onPress={() => openBrowser(this.data.link, this.colors.primary)}
159
+                            onPress={() => openBrowser(this.data.link, this.props.theme.colors.primary)}
173 160
                             style={styles.editButton}>
174 161
                             {i18n.t("profileScreen.editInformation")}
175 162
                         </Button>
@@ -193,7 +180,7 @@ class ProfileScreen extends React.Component<Props, State> {
193 180
                     left={(props) => <Avatar.Icon
194 181
                         {...props}
195 182
                         icon="account-group"
196
-                        color={this.colors.primary}
183
+                        color={this.props.theme.colors.primary}
197 184
                         style={styles.icon}
198 185
                     />}
199 186
                 />
@@ -219,7 +206,7 @@ class ProfileScreen extends React.Component<Props, State> {
219 206
                     left={(props) => <Avatar.Icon
220 207
                         {...props}
221 208
                         icon="credit-card"
222
-                        color={this.colors.primary}
209
+                        color={this.props.theme.colors.primary}
223 210
                         style={styles.icon}
224 211
                     />}
225 212
                 />
@@ -243,7 +230,7 @@ class ProfileScreen extends React.Component<Props, State> {
243 230
                 title={state ? i18n.t("profileScreen.membershipPayed") : i18n.t("profileScreen.membershipNotPayed")}
244 231
                 left={props => <List.Icon
245 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 234
                     icon={state ? 'check' : 'close'}
248 235
                 />}
249 236
             />
@@ -270,7 +257,7 @@ class ProfileScreen extends React.Component<Props, State> {
270 257
         let icon = (props) => <List.Icon {...props} icon="chevron-right"/>;
271 258
         if (item.is_manager) {
272 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 262
         return <List.Item
276 263
             title={item.name}

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

@@ -2,8 +2,6 @@
2 2
 
3 3
 import * as React from 'react';
4 4
 import {ScrollView, View} from 'react-native';
5
-import HTML from "react-native-render-html";
6
-import {Linking} from "expo";
7 5
 import {getDateOnlyString, getFormattedEventTime} from '../../utils/Planning';
8 6
 import {Card, withTheme} from 'react-native-paper';
9 7
 import DateManager from "../../managers/DateManager";
@@ -11,6 +9,7 @@ import ImageModal from 'react-native-image-modal';
11 9
 import BasicLoadingScreen from "../../components/Custom/BasicLoadingScreen";
12 10
 import {apiRequest} from "../../utils/WebData";
13 11
 import ErrorView from "../../components/Custom/ErrorView";
12
+import CustomHTML from "../../components/Custom/CustomHTML";
14 13
 
15 14
 type Props = {
16 15
     navigation: Object,
@@ -21,10 +20,6 @@ type State = {
21 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 23
 const CLUB_INFO_PATH = "event/info";
29 24
 
30 25
 /**
@@ -111,14 +106,8 @@ class PlanningDisplayScreen extends React.Component<Props, State> {
111 106
                     : <View/>}
112 107
 
113 108
                 {this.displayData.description !== null ?
114
-                    // Surround description with div to allow text styling if the description is not html
115 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 111
                     </Card.Content>
123 112
                     : <View/>}
124 113
             </ScrollView>
@@ -131,7 +120,7 @@ class PlanningDisplayScreen extends React.Component<Props, State> {
131 120
         else if (this.errorCode === 0)
132 121
             return this.getContent();
133 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