Application Android et IOS pour l'amicale des élèves
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

DebugScreen.js 5.8KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230
  1. /*
  2. * Copyright (c) 2019 - 2020 Arnaud Vergnet.
  3. *
  4. * This file is part of Campus INSAT.
  5. *
  6. * Campus INSAT is free software: you can redistribute it and/or modify
  7. * it under the terms of the GNU General Public License as published by
  8. * the Free Software Foundation, either version 3 of the License, or
  9. * (at your option) any later version.
  10. *
  11. * Campus INSAT is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  14. * GNU General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU General Public License
  17. * along with Campus INSAT. If not, see <https://www.gnu.org/licenses/>.
  18. */
  19. // @flow
  20. import * as React from 'react';
  21. import {View} from 'react-native';
  22. import {
  23. Button,
  24. List,
  25. Subheading,
  26. TextInput,
  27. Title,
  28. withTheme,
  29. } from 'react-native-paper';
  30. import {Modalize} from 'react-native-modalize';
  31. import CustomModal from '../../components/Overrides/CustomModal';
  32. import AsyncStorageManager from '../../managers/AsyncStorageManager';
  33. import type {CustomThemeType} from '../../managers/ThemeManager';
  34. import CollapsibleFlatList from '../../components/Collapsible/CollapsibleFlatList';
  35. type PreferenceItemType = {
  36. key: string,
  37. default: string,
  38. current: string,
  39. };
  40. type PropsType = {
  41. theme: CustomThemeType,
  42. };
  43. type StateType = {
  44. modalCurrentDisplayItem: PreferenceItemType,
  45. currentPreferences: Array<PreferenceItemType>,
  46. };
  47. /**
  48. * Class defining the Debug screen.
  49. * This screen allows the user to get and modify information on the app/device.
  50. */
  51. class DebugScreen extends React.Component<PropsType, StateType> {
  52. modalRef: Modalize;
  53. modalInputValue: string;
  54. /**
  55. * Copies user preferences to state for easier manipulation
  56. *
  57. * @param props
  58. */
  59. constructor(props: PropsType) {
  60. super(props);
  61. this.modalInputValue = '';
  62. const currentPreferences: Array<PreferenceItemType> = [];
  63. // eslint-disable-next-line flowtype/no-weak-types
  64. Object.values(AsyncStorageManager.PREFERENCES).forEach((object: any) => {
  65. const newObject: PreferenceItemType = {...object};
  66. newObject.current = AsyncStorageManager.getString(newObject.key);
  67. currentPreferences.push(newObject);
  68. });
  69. this.state = {
  70. modalCurrentDisplayItem: {},
  71. currentPreferences,
  72. };
  73. }
  74. /**
  75. * Gets the edit modal content
  76. *
  77. * @return {*}
  78. */
  79. getModalContent(): React.Node {
  80. const {props, state} = this;
  81. return (
  82. <View
  83. style={{
  84. flex: 1,
  85. padding: 20,
  86. }}>
  87. <Title>{state.modalCurrentDisplayItem.key}</Title>
  88. <Subheading>
  89. Default: {state.modalCurrentDisplayItem.default}
  90. </Subheading>
  91. <Subheading>
  92. Current: {state.modalCurrentDisplayItem.current}
  93. </Subheading>
  94. <TextInput
  95. label="New Value"
  96. onChangeText={(text: string) => {
  97. this.modalInputValue = text;
  98. }}
  99. />
  100. <View
  101. style={{
  102. flexDirection: 'row',
  103. marginTop: 10,
  104. }}>
  105. <Button
  106. mode="contained"
  107. dark
  108. color={props.theme.colors.success}
  109. onPress={() => {
  110. this.saveNewPrefs(
  111. state.modalCurrentDisplayItem.key,
  112. this.modalInputValue,
  113. );
  114. }}>
  115. Save new value
  116. </Button>
  117. <Button
  118. mode="contained"
  119. dark
  120. color={props.theme.colors.danger}
  121. onPress={() => {
  122. this.saveNewPrefs(
  123. state.modalCurrentDisplayItem.key,
  124. state.modalCurrentDisplayItem.default,
  125. );
  126. }}>
  127. Reset to default
  128. </Button>
  129. </View>
  130. </View>
  131. );
  132. }
  133. getRenderItem = ({item}: {item: PreferenceItemType}): React.Node => {
  134. return (
  135. <List.Item
  136. title={item.key}
  137. description="Click to edit"
  138. onPress={() => {
  139. this.showEditModal(item);
  140. }}
  141. />
  142. );
  143. };
  144. /**
  145. * Callback used when receiving the modal ref
  146. *
  147. * @param ref
  148. */
  149. onModalRef = (ref: Modalize) => {
  150. this.modalRef = ref;
  151. };
  152. /**
  153. * Shows the edit modal
  154. *
  155. * @param item
  156. */
  157. showEditModal(item: PreferenceItemType) {
  158. this.setState({
  159. modalCurrentDisplayItem: item,
  160. });
  161. if (this.modalRef) this.modalRef.open();
  162. }
  163. /**
  164. * Finds the index of the given key in the preferences array
  165. *
  166. * @param key THe key to find the index of
  167. * @returns {number}
  168. */
  169. findIndexOfKey(key: string): number {
  170. const {currentPreferences} = this.state;
  171. let index = -1;
  172. for (let i = 0; i < currentPreferences.length; i += 1) {
  173. if (currentPreferences[i].key === key) {
  174. index = i;
  175. break;
  176. }
  177. }
  178. return index;
  179. }
  180. /**
  181. * Saves the new value of the given preference
  182. *
  183. * @param key The pref key
  184. * @param value The pref value
  185. */
  186. saveNewPrefs(key: string, value: string) {
  187. this.setState((prevState: StateType): {
  188. currentPreferences: Array<PreferenceItemType>,
  189. } => {
  190. const currentPreferences = [...prevState.currentPreferences];
  191. currentPreferences[this.findIndexOfKey(key)].current = value;
  192. return {currentPreferences};
  193. });
  194. AsyncStorageManager.set(key, value);
  195. this.modalRef.close();
  196. }
  197. render(): React.Node {
  198. const {state} = this;
  199. return (
  200. <View>
  201. <CustomModal onRef={this.onModalRef}>
  202. {this.getModalContent()}
  203. </CustomModal>
  204. {/* $FlowFixMe */}
  205. <CollapsibleFlatList
  206. data={state.currentPreferences}
  207. extraData={state.currentPreferences}
  208. renderItem={this.getRenderItem}
  209. />
  210. </View>
  211. );
  212. }
  213. }
  214. export default withTheme(DebugScreen);