@pi-spi/app 1.6.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +64 -30
- package/example/App.tsx +27 -24
- package/lib/module/core/assets.js +0 -7
- package/lib/module/core/assets.js.map +1 -1
- package/lib/module/core/di.js +17 -8
- package/lib/module/core/di.js.map +1 -1
- package/lib/module/core/pi_spi_custom_theme.js +22 -10
- package/lib/module/core/pi_spi_custom_theme.js.map +1 -1
- package/lib/module/core/pi_spi_sdk_config.js +22 -8
- package/lib/module/core/pi_spi_sdk_config.js.map +1 -1
- package/lib/module/core/theme.js +345 -225
- package/lib/module/core/theme.js.map +1 -1
- package/lib/module/index.js +1 -1
- package/lib/module/index.js.map +1 -1
- package/lib/module/l10n/app_localizations.js.map +1 -1
- package/lib/module/l10n/app_localizations_en.js +14 -0
- package/lib/module/l10n/app_localizations_en.js.map +1 -1
- package/lib/module/l10n/app_localizations_fr.js +14 -0
- package/lib/module/l10n/app_localizations_fr.js.map +1 -1
- package/lib/module/l10n/app_localizations_pt.js +14 -0
- package/lib/module/l10n/app_localizations_pt.js.map +1 -1
- package/lib/module/modules/config/domain/models/config_keys.js +3 -1
- package/lib/module/modules/config/domain/models/config_keys.js.map +1 -1
- package/lib/module/modules/config/domain/services/config_service.js +31 -2
- package/lib/module/modules/config/domain/services/config_service.js.map +1 -1
- package/lib/module/modules/home/presentation/pages/home_tab_compte.js +0 -1
- package/lib/module/modules/home/presentation/pages/home_tab_compte.js.map +1 -1
- package/lib/module/modules/home/presentation/pages/home_tab_compte_more_menu.js +38 -37
- package/lib/module/modules/home/presentation/pages/home_tab_compte_more_menu.js.map +1 -1
- package/lib/module/modules/profile/presentation/pages/parametre/profile_parametre_page.js +2 -2
- package/lib/module/modules/profile/presentation/pages/parametre/profile_parametre_page.js.map +1 -1
- package/lib/module/modules/profile/presentation/pages/parametre/profile_parametre_page_qrcode.js +2 -2
- package/lib/module/modules/profile/presentation/pages/parametre/profile_parametre_page_qrcode.js.map +1 -1
- package/lib/module/modules/profile/presentation/pages/parametre/profile_parametre_page_theme.js +135 -199
- package/lib/module/modules/profile/presentation/pages/parametre/profile_parametre_page_theme.js.map +1 -1
- package/lib/module/modules/profile/presentation/pages/profile_menu.js +4 -3
- package/lib/module/modules/profile/presentation/pages/profile_menu.js.map +1 -1
- package/lib/module/modules/transactions/presentation/pages/transaction_details/transaction_details_page_recu.js +3 -1
- package/lib/module/modules/transactions/presentation/pages/transaction_details/transaction_details_page_recu.js.map +1 -1
- package/lib/module/modules/transactions/presentation/pages/transaction_search/transaction_search_page_filters.js +5 -4
- package/lib/module/modules/transactions/presentation/pages/transaction_search/transaction_search_page_filters.js.map +1 -1
- package/lib/module/modules/transactions/presentation/pages/transaction_split/transaction_split_page_repartition.js +2 -2
- package/lib/module/modules/transactions/presentation/pages/transaction_split/transaction_split_page_repartition.js.map +1 -1
- package/lib/module/pi_spi_sdk_entry.js +7 -2
- package/lib/module/pi_spi_sdk_entry.js.map +1 -1
- package/lib/module/shared/widgets/custom_progressbar.js +3 -2
- package/lib/module/shared/widgets/custom_progressbar.js.map +1 -1
- package/lib/module/shared/widgets/selection.js +1 -1
- package/lib/module/shared/widgets/selection.js.map +1 -1
- package/lib/typescript/src/core/assets.d.ts +0 -7
- package/lib/typescript/src/core/assets.d.ts.map +1 -1
- package/lib/typescript/src/core/di.d.ts.map +1 -1
- package/lib/typescript/src/core/pi_spi_custom_theme.d.ts +17 -8
- package/lib/typescript/src/core/pi_spi_custom_theme.d.ts.map +1 -1
- package/lib/typescript/src/core/pi_spi_sdk_config.d.ts +22 -8
- package/lib/typescript/src/core/pi_spi_sdk_config.d.ts.map +1 -1
- package/lib/typescript/src/core/theme.d.ts +123 -53
- package/lib/typescript/src/core/theme.d.ts.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -1
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/lib/typescript/src/l10n/app_localizations.d.ts +28 -0
- package/lib/typescript/src/l10n/app_localizations.d.ts.map +1 -1
- package/lib/typescript/src/l10n/app_localizations_en.d.ts.map +1 -1
- package/lib/typescript/src/l10n/app_localizations_fr.d.ts.map +1 -1
- package/lib/typescript/src/l10n/app_localizations_pt.d.ts.map +1 -1
- package/lib/typescript/src/modules/config/domain/models/config_keys.d.ts +3 -1
- package/lib/typescript/src/modules/config/domain/models/config_keys.d.ts.map +1 -1
- package/lib/typescript/src/modules/config/domain/services/config_service.d.ts +7 -0
- package/lib/typescript/src/modules/config/domain/services/config_service.d.ts.map +1 -1
- package/lib/typescript/src/modules/home/presentation/pages/home_tab_compte_more_menu.d.ts +2 -0
- package/lib/typescript/src/modules/home/presentation/pages/home_tab_compte_more_menu.d.ts.map +1 -1
- package/lib/typescript/src/modules/profile/presentation/pages/parametre/profile_parametre_page.d.ts.map +1 -1
- package/lib/typescript/src/modules/profile/presentation/pages/parametre/profile_parametre_page_theme.d.ts +1 -1
- package/lib/typescript/src/modules/profile/presentation/pages/parametre/profile_parametre_page_theme.d.ts.map +1 -1
- package/lib/typescript/src/shared/widgets/custom_progressbar.d.ts.map +1 -1
- package/lib/typescript/src/shared/widgets/selection.d.ts +1 -1
- package/lib/typescript/src/shared/widgets/selection.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/core/assets.ts +0 -7
- package/src/core/di.ts +13 -8
- package/src/core/pi_spi_custom_theme.ts +22 -15
- package/src/core/pi_spi_sdk_config.ts +27 -9
- package/src/core/theme.ts +381 -269
- package/src/index.ts +1 -1
- package/src/l10n/app_localizations.ts +28 -0
- package/src/l10n/app_localizations_en.ts +14 -0
- package/src/l10n/app_localizations_fr.ts +14 -0
- package/src/l10n/app_localizations_pt.ts +14 -0
- package/src/modules/config/domain/models/config_keys.ts +3 -1
- package/src/modules/config/domain/services/config_service.ts +31 -2
- package/src/modules/home/presentation/pages/home_tab_compte.tsx +1 -1
- package/src/modules/home/presentation/pages/home_tab_compte_more_menu.tsx +34 -42
- package/src/modules/profile/presentation/pages/parametre/profile_parametre_page.tsx +2 -5
- package/src/modules/profile/presentation/pages/parametre/profile_parametre_page_qrcode.tsx +2 -2
- package/src/modules/profile/presentation/pages/parametre/profile_parametre_page_theme.tsx +105 -148
- package/src/modules/profile/presentation/pages/profile_menu.tsx +2 -2
- package/src/modules/transactions/presentation/pages/transaction_details/transaction_details_page_recu.tsx +3 -1
- package/src/modules/transactions/presentation/pages/transaction_search/transaction_search_page_filters.tsx +4 -4
- package/src/modules/transactions/presentation/pages/transaction_split/transaction_split_page_repartition.tsx +2 -2
- package/src/pi_spi_sdk_entry.tsx +9 -2
- package/src/shared/widgets/custom_progressbar.tsx +3 -2
- package/src/shared/widgets/selection.tsx +1 -1
- package/assets/images/theme_light_blue.jpeg +0 -0
- package/assets/images/theme_light_green.jpeg +0 -0
- package/assets/images/theme_light_orange.jpeg +0 -0
- package/assets/images/theme_light_pink.jpeg +0 -0
- package/assets/images/theme_light_purple.jpeg +0 -0
- package/assets/images/theme_light_red.jpeg +0 -0
- package/assets/images/theme_light_yellow.jpeg +0 -0
package/src/index.ts
CHANGED
|
@@ -22,7 +22,7 @@ export {
|
|
|
22
22
|
type PiSpiLogLevel,
|
|
23
23
|
} from './core/pi_spi_sdk_config';
|
|
24
24
|
export { PiSpiCustomTheme } from './core/pi_spi_custom_theme';
|
|
25
|
-
export { Themes, type ThemeData } from './core/theme';
|
|
25
|
+
export { Accents, Themes, type ThemeData } from './core/theme';
|
|
26
26
|
export {
|
|
27
27
|
type AppLocalizations,
|
|
28
28
|
type SupportedLocaleCode,
|
|
@@ -915,6 +915,8 @@ export interface AppLocalizations {
|
|
|
915
915
|
readonly transactionDetailsCancelRejectMessage: string;
|
|
916
916
|
/** Send receipt */
|
|
917
917
|
readonly transactionDetailsRecuTitle: string;
|
|
918
|
+
/** Issued on: */
|
|
919
|
+
readonly transactionDetailsRecuPdfEditeLe: string;
|
|
918
920
|
/** You can download or share the PDF file */
|
|
919
921
|
readonly transactionDetailsRecuSubTitle: string;
|
|
920
922
|
/** Identifier */
|
|
@@ -1215,6 +1217,32 @@ export interface AppLocalizations {
|
|
|
1215
1217
|
readonly appSettingPageMenuThemeDefault: string;
|
|
1216
1218
|
/** Apparence */
|
|
1217
1219
|
readonly appSettingPageMenuThemePageTitle: string;
|
|
1220
|
+
/** Theme */
|
|
1221
|
+
readonly appSettingPageThemeSection: string;
|
|
1222
|
+
/** Accent colour */
|
|
1223
|
+
readonly appSettingPageAccentSection: string;
|
|
1224
|
+
/** Default */
|
|
1225
|
+
readonly appSettingPageAccentDefaut: string;
|
|
1226
|
+
/** Green */
|
|
1227
|
+
readonly appSettingPageAccentVert: string;
|
|
1228
|
+
/** Blue */
|
|
1229
|
+
readonly appSettingPageAccentBleu: string;
|
|
1230
|
+
/** Red */
|
|
1231
|
+
readonly appSettingPageAccentRouge: string;
|
|
1232
|
+
/** Orange */
|
|
1233
|
+
readonly appSettingPageAccentOrange: string;
|
|
1234
|
+
/** Purple */
|
|
1235
|
+
readonly appSettingPageAccentViolet: string;
|
|
1236
|
+
/** Pink */
|
|
1237
|
+
readonly appSettingPageAccentRose: string;
|
|
1238
|
+
/** Turquoise */
|
|
1239
|
+
readonly appSettingPageAccentTurquoise: string;
|
|
1240
|
+
/** Terracotta */
|
|
1241
|
+
readonly appSettingPageAccentTerracotta: string;
|
|
1242
|
+
/** Burgundy */
|
|
1243
|
+
readonly appSettingPageAccentBordeaux: string;
|
|
1244
|
+
/** Slate */
|
|
1245
|
+
readonly appSettingPageAccentArdoise: string;
|
|
1218
1246
|
/** My QR code by default */
|
|
1219
1247
|
readonly appSettingPageMenuQrCodeTitle: string;
|
|
1220
1248
|
/** Enable to display your QR Code by default */
|
|
@@ -464,6 +464,7 @@ If this request comes from someone you trust, simply add their alias to your con
|
|
|
464
464
|
transactionDetailsCancelReasonLabel: `Reason`,
|
|
465
465
|
transactionDetailsCancelRejectMessage: `The cancellation request has been successfully rejected`,
|
|
466
466
|
transactionDetailsRecuTitle: `Send receipt`,
|
|
467
|
+
transactionDetailsRecuPdfEditeLe: `Issued on:`,
|
|
467
468
|
transactionDetailsRecuSubTitle: `You can download or share the PDF file`,
|
|
468
469
|
transactionDetailsRecuInfoIdentifiant: `Identifier`,
|
|
469
470
|
transactionDetailsRecuInfoReference: `Reference`,
|
|
@@ -619,6 +620,19 @@ Scanning will be automatic`,
|
|
|
619
620
|
appSettingPageMenuThemeCustom: `App theme`,
|
|
620
621
|
appSettingPageMenuThemeDefault: `System`,
|
|
621
622
|
appSettingPageMenuThemePageTitle: `Apparence`,
|
|
623
|
+
appSettingPageThemeSection: `Theme`,
|
|
624
|
+
appSettingPageAccentSection: `Accent colour`,
|
|
625
|
+
appSettingPageAccentDefaut: `Default`,
|
|
626
|
+
appSettingPageAccentVert: `Green`,
|
|
627
|
+
appSettingPageAccentBleu: `Blue`,
|
|
628
|
+
appSettingPageAccentRouge: `Red`,
|
|
629
|
+
appSettingPageAccentOrange: `Orange`,
|
|
630
|
+
appSettingPageAccentViolet: `Purple`,
|
|
631
|
+
appSettingPageAccentRose: `Pink`,
|
|
632
|
+
appSettingPageAccentTurquoise: `Turquoise`,
|
|
633
|
+
appSettingPageAccentTerracotta: `Terracotta`,
|
|
634
|
+
appSettingPageAccentBordeaux: `Burgundy`,
|
|
635
|
+
appSettingPageAccentArdoise: `Slate`,
|
|
622
636
|
appSettingPageMenuQrCodeTitle: `My QR code by default`,
|
|
623
637
|
appSettingPageMenuQrCodeSelectTitle: `Enable to display your QR Code by default`,
|
|
624
638
|
appSettingPageMenuQrCodeDeselectTitle: `Disable to display the camera by default`,
|
|
@@ -464,6 +464,7 @@ Si cette demande provient d'une personne de confiance, il vous suffit d'ajouter
|
|
|
464
464
|
transactionDetailsCancelReasonLabel: `Raison`,
|
|
465
465
|
transactionDetailsCancelRejectMessage: `La demande d’annulation est rejetée avec succès`,
|
|
466
466
|
transactionDetailsRecuTitle: `Reçu de l'envoi`,
|
|
467
|
+
transactionDetailsRecuPdfEditeLe: `Edité le :`,
|
|
467
468
|
transactionDetailsRecuSubTitle: `Vous pouvez partager ou télécharger le PDF`,
|
|
468
469
|
transactionDetailsRecuInfoIdentifiant: `Identifiant`,
|
|
469
470
|
transactionDetailsRecuInfoReference: `Référence`,
|
|
@@ -618,6 +619,19 @@ Le scan se fait automatiquement`,
|
|
|
618
619
|
appSettingPageMenuThemeCustom: `Thème de l'application`,
|
|
619
620
|
appSettingPageMenuThemeDefault: `Système`,
|
|
620
621
|
appSettingPageMenuThemePageTitle: `Apparence`,
|
|
622
|
+
appSettingPageThemeSection: `Thème`,
|
|
623
|
+
appSettingPageAccentSection: `Couleur d'accentuation`,
|
|
624
|
+
appSettingPageAccentDefaut: `Défaut`,
|
|
625
|
+
appSettingPageAccentVert: `Vert`,
|
|
626
|
+
appSettingPageAccentBleu: `Bleu`,
|
|
627
|
+
appSettingPageAccentRouge: `Rouge`,
|
|
628
|
+
appSettingPageAccentOrange: `Orange`,
|
|
629
|
+
appSettingPageAccentViolet: `Violet`,
|
|
630
|
+
appSettingPageAccentRose: `Rose`,
|
|
631
|
+
appSettingPageAccentTurquoise: `Turquoise`,
|
|
632
|
+
appSettingPageAccentTerracotta: `Terracotta`,
|
|
633
|
+
appSettingPageAccentBordeaux: `Bordeaux`,
|
|
634
|
+
appSettingPageAccentArdoise: `Ardoise`,
|
|
621
635
|
appSettingPageMenuQrCodeTitle: `Mon QR code par défaut`,
|
|
622
636
|
appSettingPageMenuQrCodeSelectTitle: `Activer pour afficher votre QR Code par défaut`,
|
|
623
637
|
appSettingPageMenuQrCodeDeselectTitle: `Désactiver pour afficher la caméra par défaut`,
|
|
@@ -464,6 +464,7 @@ Se este pedido for de uma pessoa de confiança, basta adicionar o alias aos seus
|
|
|
464
464
|
transactionDetailsCancelReasonLabel: `Razão`,
|
|
465
465
|
transactionDetailsCancelRejectMessage: `A demanda de cancelamento foi rejeitada com sucesso`,
|
|
466
466
|
transactionDetailsRecuTitle: `Recebido de envio`,
|
|
467
|
+
transactionDetailsRecuPdfEditeLe: `Emitido em:`,
|
|
467
468
|
transactionDetailsRecuSubTitle: `Você pode compartilhar ou baixar o PDF`,
|
|
468
469
|
transactionDetailsRecuInfoIdentifiant: `Identificador`,
|
|
469
470
|
transactionDetailsRecuInfoReference: `Referência`,
|
|
@@ -619,6 +620,19 @@ O scan é feito automaticamente`,
|
|
|
619
620
|
appSettingPageMenuThemeCustom: `Tema da aplicação`,
|
|
620
621
|
appSettingPageMenuThemeDefault: `Sistema`,
|
|
621
622
|
appSettingPageMenuThemePageTitle: `Aparência`,
|
|
623
|
+
appSettingPageThemeSection: `Tema`,
|
|
624
|
+
appSettingPageAccentSection: `Cor de destaque`,
|
|
625
|
+
appSettingPageAccentDefaut: `Padrão`,
|
|
626
|
+
appSettingPageAccentVert: `Verde`,
|
|
627
|
+
appSettingPageAccentBleu: `Azul`,
|
|
628
|
+
appSettingPageAccentRouge: `Vermelho`,
|
|
629
|
+
appSettingPageAccentOrange: `Laranja`,
|
|
630
|
+
appSettingPageAccentViolet: `Roxo`,
|
|
631
|
+
appSettingPageAccentRose: `Rosa`,
|
|
632
|
+
appSettingPageAccentTurquoise: `Turquesa`,
|
|
633
|
+
appSettingPageAccentTerracotta: `Terracota`,
|
|
634
|
+
appSettingPageAccentBordeaux: `Bordô`,
|
|
635
|
+
appSettingPageAccentArdoise: `Ardósia`,
|
|
622
636
|
appSettingPageMenuQrCodeTitle: `Meu QR Code por defeito`,
|
|
623
637
|
appSettingPageMenuQrCodeSelectTitle: `Ativar para exibir o meu QR Code por defeito`,
|
|
624
638
|
appSettingPageMenuQrCodeDeselectTitle: `Desativar para exibir a câmera por defeito`,
|
|
@@ -6,8 +6,10 @@ export enum ConfigKey {
|
|
|
6
6
|
/** l'utilisateur a passé l'introduction */
|
|
7
7
|
introductionPassed = 'INTRODUCTION_PASSED',
|
|
8
8
|
|
|
9
|
-
/** theme de l'utilisateur */
|
|
9
|
+
/** theme de l'utilisateur : système, clair ou sombre */
|
|
10
10
|
preferedTheme = 'PREFERED_THEME',
|
|
11
|
+
/** Couleur d'accentuation (PI-SPI par défaut) */
|
|
12
|
+
preferedAccent = 'PREFERED_ACCENT',
|
|
11
13
|
|
|
12
14
|
/** Permission notification */
|
|
13
15
|
permissionNotification = 'PERMISSION_NOTIFICATION',
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { ConfigInputPort } from '../../ports/input/config_input_port';
|
|
2
2
|
import type { ConfigOutputPort } from '../../ports/output/config_output_port';
|
|
3
|
-
import { configKeyValues } from '../models/config_keys';
|
|
3
|
+
import { ConfigKey, configKeyValues } from '../models/config_keys';
|
|
4
4
|
import type { ConfigParams } from '../models/config_params';
|
|
5
5
|
|
|
6
6
|
/** Service contenant la logique de gestion des configurations */
|
|
@@ -11,9 +11,38 @@ export class ConfigService implements ConfigInputPort {
|
|
|
11
11
|
*/
|
|
12
12
|
constructor(readonly configOutputPort: ConfigOutputPort) {}
|
|
13
13
|
|
|
14
|
+
/**
|
|
15
|
+
* Anciens thèmes de couleur, remplacés par le thème clair et une couleur
|
|
16
|
+
* d'accentuation (le jaune, trop proche de l'ambre, devient PI-SPI)
|
|
17
|
+
*/
|
|
18
|
+
static readonly anciensThemes: Readonly<Record<string, string>> = {
|
|
19
|
+
yellowTheme: 'pispi',
|
|
20
|
+
greenTheme: 'vert',
|
|
21
|
+
blueTheme: 'bleu',
|
|
22
|
+
redTheme: 'rouge',
|
|
23
|
+
orangeTheme: 'orange',
|
|
24
|
+
purpleTheme: 'violet',
|
|
25
|
+
pinkTheme: 'rose',
|
|
26
|
+
// Thème personnalisé de l'hôte : sa couleur devient l'accent
|
|
27
|
+
customTheme: 'application',
|
|
28
|
+
};
|
|
29
|
+
|
|
14
30
|
recuperer(): ConfigParams {
|
|
15
31
|
// Récuperer toute la config et Appeler le systeme de stockage
|
|
16
|
-
|
|
32
|
+
const config = this.configOutputPort.recuperer([...configKeyValues]);
|
|
33
|
+
this.migrerTheme(config);
|
|
34
|
+
return config;
|
|
35
|
+
}
|
|
36
|
+
|
|
37
|
+
/** Convertit une seule fois un ancien thème de couleur en thème clair et couleur d'accentuation, et l'enregistre */
|
|
38
|
+
private migrerTheme(config: ConfigParams): void {
|
|
39
|
+
const ancien = config.params[ConfigKey.preferedTheme];
|
|
40
|
+
const accent = ancien != null ? ConfigService.anciensThemes[ancien] : undefined;
|
|
41
|
+
if (accent == null) return;
|
|
42
|
+
config.params[ConfigKey.preferedTheme] = 'lightTheme';
|
|
43
|
+
config.params[ConfigKey.preferedAccent] = accent;
|
|
44
|
+
void this.configOutputPort.modifier(ConfigKey.preferedTheme, 'lightTheme');
|
|
45
|
+
void this.configOutputPort.modifier(ConfigKey.preferedAccent, accent);
|
|
17
46
|
}
|
|
18
47
|
|
|
19
48
|
async modifier(key: string, value: string): Promise<void> {
|
|
@@ -75,7 +75,7 @@ export function HomeTabCompte() {
|
|
|
75
75
|
<CtaWidget
|
|
76
76
|
icon={(color) => <MaterialIcons name="more-horiz" size={30} color={color} />}
|
|
77
77
|
label={traductions.homeActionMore}
|
|
78
|
-
action={hasAlias ? () => void showModalBottomSheet(router, {
|
|
78
|
+
action={hasAlias ? () => void showModalBottomSheet(router, { builder: () => <HomeTabCompteMoreMenu /> }) : null}
|
|
79
79
|
/>
|
|
80
80
|
</View>
|
|
81
81
|
<View style={styles.gap14} />
|
|
@@ -1,71 +1,63 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { useSafeAreaInsets } from 'react-native-safe-area-context';
|
|
1
|
+
import { StyleSheet, View } from 'react-native';
|
|
3
2
|
|
|
4
3
|
import { Images } from '../../../../core/assets';
|
|
5
4
|
import { AppRouter, useAppRouter } from '../../../../core/router';
|
|
6
|
-
import { useTheme } from '../../../../core/theme';
|
|
7
5
|
import { useAppLocalizations } from '../../../../l10n/localizations';
|
|
8
|
-
import {
|
|
9
|
-
import {
|
|
6
|
+
import { SelectionSheet } from '../../../../shared/widgets/selection';
|
|
7
|
+
import { ProfileMenuTile, ProfilePageMenu } from '../../../profile/presentation/pages/profile_menu';
|
|
10
8
|
|
|
11
9
|
/**
|
|
12
10
|
* Menu « Plus » de l'accueil. Le participant peut personnaliser ce menu
|
|
13
11
|
* pour y ajouter des fonctionnalités propres à son système.
|
|
12
|
+
* Même feuille que celles du profil : à ouvrir avec showModalBottomSheet
|
|
13
|
+
* sans `themed`, la feuille dessine elle-même son fond.
|
|
14
14
|
*/
|
|
15
15
|
export function HomeTabCompteMoreMenu() {
|
|
16
16
|
const traductions = useAppLocalizations();
|
|
17
|
-
const theme = useTheme();
|
|
18
17
|
const router = useAppRouter();
|
|
19
|
-
const { height } = useWindowDimensions();
|
|
20
|
-
const insets = useSafeAreaInsets();
|
|
21
18
|
// Fermer le menu avant d'ouvrir la page : sinon il reste affiché par-dessus
|
|
22
19
|
const open = (location: string) => {
|
|
23
20
|
AppRouter.pop(router);
|
|
24
21
|
void AppRouter.push(router, location);
|
|
25
22
|
};
|
|
26
23
|
return (
|
|
27
|
-
<
|
|
28
|
-
|
|
29
|
-
styles.
|
|
30
|
-
|
|
31
|
-
]}
|
|
32
|
-
>
|
|
33
|
-
<Card>
|
|
34
|
-
<ScrollView>
|
|
35
|
-
<MenuActionsWidget
|
|
24
|
+
<SelectionSheet
|
|
25
|
+
contenu={
|
|
26
|
+
<View style={styles.contenu}>
|
|
27
|
+
<ProfilePageMenu
|
|
36
28
|
items={[
|
|
37
29
|
// Programmer un paiement
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
traductions.
|
|
42
|
-
|
|
43
|
-
{
|
|
44
|
-
|
|
30
|
+
<ProfileMenuTile
|
|
31
|
+
key="programmer"
|
|
32
|
+
image={Images.homeFooterTransfer}
|
|
33
|
+
titre={traductions.homeActionMoreSheetProgrammerTitle}
|
|
34
|
+
sousTitre={traductions.homeActionMoreSheetProgrammerSubTitle}
|
|
35
|
+
onPress={() => open(AppRouter.subscriptionSchedule)}
|
|
36
|
+
/>,
|
|
45
37
|
// Trouver un abonnement
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
traductions.
|
|
50
|
-
|
|
51
|
-
{
|
|
52
|
-
|
|
38
|
+
<ProfileMenuTile
|
|
39
|
+
key="abonnement"
|
|
40
|
+
image={Images.homeMoreFindSubscription}
|
|
41
|
+
titre={traductions.homeActionMoreSheetAbonnementTitle}
|
|
42
|
+
sousTitre={traductions.homeActionMoreSheetAbonnementSubTitle}
|
|
43
|
+
onPress={() => open(AppRouter.subscriptionSubscribe)}
|
|
44
|
+
/>,
|
|
53
45
|
// Partager dépenses
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
traductions.
|
|
58
|
-
|
|
59
|
-
{
|
|
60
|
-
|
|
46
|
+
<ProfileMenuTile
|
|
47
|
+
key="partager"
|
|
48
|
+
image={Images.homeMoreSplitPayments}
|
|
49
|
+
titre={traductions.homeActionMoreSheetPartagerTitle}
|
|
50
|
+
sousTitre={traductions.homeActionMoreSheetPartagerSubTitle}
|
|
51
|
+
onPress={() => open(AppRouter.transactionSplitPaymentTx)}
|
|
52
|
+
/>,
|
|
61
53
|
]}
|
|
62
54
|
/>
|
|
63
|
-
</
|
|
64
|
-
|
|
65
|
-
|
|
55
|
+
</View>
|
|
56
|
+
}
|
|
57
|
+
/>
|
|
66
58
|
);
|
|
67
59
|
}
|
|
68
60
|
|
|
69
61
|
const styles = StyleSheet.create({
|
|
70
|
-
|
|
62
|
+
contenu: { paddingHorizontal: 16, paddingTop: 8, paddingBottom: 20 },
|
|
71
63
|
});
|
|
@@ -46,10 +46,7 @@ function menuItems(traductions: AppLocalizations, configParams: ConfigParams): P
|
|
|
46
46
|
if (Di.config.appConfig.canChangeTheme) {
|
|
47
47
|
items.push(
|
|
48
48
|
new ProfileItem(Images.iconsTheme, traductions.appSettingPageMenuThemeTitle, AppRouter.profileParametreTheme, {
|
|
49
|
-
subtitle:
|
|
50
|
-
params[ConfigKey.preferedTheme] === Themer.customThemeCode
|
|
51
|
-
? traductions.appSettingPageMenuThemeCustom
|
|
52
|
-
: Themes.label(theme, traductions),
|
|
49
|
+
subtitle: `${Themes.label(theme, traductions)} · ${Themer.accentLabel(traductions, params[ConfigKey.preferedAccent])}`,
|
|
53
50
|
}),
|
|
54
51
|
);
|
|
55
52
|
}
|
|
@@ -76,7 +73,7 @@ export function ProfileParametrePage() {
|
|
|
76
73
|
(_p, current) =>
|
|
77
74
|
current instanceof ConfigLoadedState &&
|
|
78
75
|
current.updatedKey != null &&
|
|
79
|
-
[ConfigKey.showQRcode, ConfigKey.preferedTheme, ConfigKey.notificationStatus, ConfigKey.notificationAlertSound].includes(
|
|
76
|
+
[ConfigKey.showQRcode, ConfigKey.preferedTheme, ConfigKey.preferedAccent, ConfigKey.notificationStatus, ConfigKey.notificationAlertSound].includes(
|
|
80
77
|
current.updatedKey,
|
|
81
78
|
),
|
|
82
79
|
);
|
|
@@ -4,7 +4,7 @@ import { Images } from '../../../../../core/assets';
|
|
|
4
4
|
import { useBloc, useBlocBuilder } from '../../../../../core/bloc_react';
|
|
5
5
|
import { Themer, useTheme } from '../../../../../core/theme';
|
|
6
6
|
import { useAppLocalizations } from '../../../../../l10n/localizations';
|
|
7
|
-
import {
|
|
7
|
+
import { SelectionSheet } from '../../../../../shared/widgets/selection';
|
|
8
8
|
import { ConfigBloc } from '../../../../config/adapters/ui/bloc/config_bloc';
|
|
9
9
|
import { ConfigChangeEvent } from '../../../../config/adapters/ui/bloc/config_event';
|
|
10
10
|
import { ConfigLoadedState } from '../../../../config/adapters/ui/bloc/config_state';
|
|
@@ -25,7 +25,7 @@ export function ProfileParametrePageQRcode() {
|
|
|
25
25
|
const basculer = () => configBloc.add(new ConfigChangeEvent(ConfigKey.showQRcode, showQRcode ? '0' : '1'));
|
|
26
26
|
|
|
27
27
|
return (
|
|
28
|
-
<
|
|
28
|
+
<SelectionSheet
|
|
29
29
|
titre={traductions.appSettingPageMenuQrCodeTitle}
|
|
30
30
|
entete={
|
|
31
31
|
<Text style={[theme.textTheme.displaySmall, { color: Themer.neural03Color }]}>
|
|
@@ -1,11 +1,11 @@
|
|
|
1
1
|
import { MaterialIcons } from '@expo/vector-icons';
|
|
2
2
|
import { Image } from 'expo-image';
|
|
3
|
-
import { useState
|
|
3
|
+
import { useState } from 'react';
|
|
4
4
|
import { Pressable, ScrollView, StyleSheet, Text, View } from 'react-native';
|
|
5
5
|
|
|
6
6
|
import { Images } from '../../../../../core/assets';
|
|
7
7
|
import { useBloc, useBlocBuilder } from '../../../../../core/bloc_react';
|
|
8
|
-
import { Themer, Themes, useTheme
|
|
8
|
+
import { Accents, Themer, Themes, useTheme } from '../../../../../core/theme';
|
|
9
9
|
import type { AppLocalizations } from '../../../../../l10n/app_localizations';
|
|
10
10
|
import { useAppLocalizations } from '../../../../../l10n/localizations';
|
|
11
11
|
import { Card } from '../../../../../shared/material/card';
|
|
@@ -24,20 +24,6 @@ function themeIcon(theme: Themes): number {
|
|
|
24
24
|
return Images.imageThemeLight;
|
|
25
25
|
case Themes.dark:
|
|
26
26
|
return Images.imageThemeDark;
|
|
27
|
-
case Themes.yellow:
|
|
28
|
-
return Images.imageThemeLightYellow;
|
|
29
|
-
case Themes.green:
|
|
30
|
-
return Images.imageThemeLightGreen;
|
|
31
|
-
case Themes.blue:
|
|
32
|
-
return Images.imageThemeLightBlue;
|
|
33
|
-
case Themes.red:
|
|
34
|
-
return Images.imageThemeLightRed;
|
|
35
|
-
case Themes.orange:
|
|
36
|
-
return Images.imageThemeLightOrange;
|
|
37
|
-
case Themes.purple:
|
|
38
|
-
return Images.imageThemeLightPurple;
|
|
39
|
-
case Themes.pink:
|
|
40
|
-
return Images.imageThemeLightPink;
|
|
41
27
|
default:
|
|
42
28
|
return Images.imageThemeSystem;
|
|
43
29
|
}
|
|
@@ -47,53 +33,119 @@ function themeTitle(traductions: AppLocalizations, theme: Themes): string {
|
|
|
47
33
|
return theme === Themes.system ? traductions.appSettingPageMenuThemeDefault : Themes.label(theme, traductions);
|
|
48
34
|
}
|
|
49
35
|
|
|
50
|
-
/** Choix du thème de
|
|
36
|
+
/** Choix du thème (système, clair, sombre) et de la couleur d'accentuation (route `profileParametreTheme`). */
|
|
51
37
|
export function ProfileParametrePageTheme() {
|
|
52
38
|
const traductions = useAppLocalizations();
|
|
39
|
+
const theme = useTheme();
|
|
53
40
|
const configBloc = useBloc(ConfigBloc);
|
|
54
41
|
const state = useBlocBuilder(
|
|
55
42
|
configBloc,
|
|
56
|
-
(_p, current) =>
|
|
43
|
+
(_p, current) =>
|
|
44
|
+
current instanceof ConfigLoadedState &&
|
|
45
|
+
(current.updatedKey === ConfigKey.preferedTheme || current.updatedKey === ConfigKey.preferedAccent),
|
|
57
46
|
);
|
|
58
|
-
const currentTheme = state.configParams.params[ConfigKey.preferedTheme];
|
|
59
|
-
|
|
47
|
+
const currentTheme = Themes.fromCode(state.configParams.params[ConfigKey.preferedTheme]);
|
|
48
|
+
const currentAccent = state.configParams.params[ConfigKey.preferedAccent] ?? Accents.parDefaut;
|
|
49
|
+
const sombre = theme.brightness === 'dark';
|
|
60
50
|
const [largeurGrille, setLargeurGrille] = useState(0);
|
|
51
|
+
|
|
61
52
|
// Trois aperçus par ligne
|
|
53
|
+
const espace = 12;
|
|
62
54
|
// Arrondi vers le bas : sinon la troisième colonne peut passer à la ligne
|
|
63
|
-
const largeur = Math.floor((largeurGrille - 2 *
|
|
55
|
+
const largeur = Math.floor((largeurGrille - 2 * espace) / 3);
|
|
64
56
|
|
|
65
57
|
return (
|
|
66
58
|
<Scaffold appBar={<ProfileAppBar titre={traductions.appSettingPageMenuThemePageTitle} />}>
|
|
67
59
|
<MyPageContainer>
|
|
68
60
|
<ScrollView contentContainerStyle={styles.contenu}>
|
|
69
|
-
{/* Thème */}
|
|
70
|
-
<ProfileSectionTitre titre={traductions.
|
|
61
|
+
{/* Thème : système, clair ou sombre */}
|
|
62
|
+
<ProfileSectionTitre titre={traductions.appSettingPageThemeSection} />
|
|
71
63
|
<Card style={styles.card}>
|
|
72
64
|
<View style={styles.grille} onLayout={(e) => setLargeurGrille(e.nativeEvent.layout.width - 2 * 14)}>
|
|
73
|
-
{largeurGrille > 0 &&
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
<
|
|
78
|
-
largeur={largeur}
|
|
79
|
-
title={traductions.appSettingPageMenuThemeCustom}
|
|
80
|
-
selected={currentTheme === Themer.customThemeCode}
|
|
81
|
-
onSelect={() => configBloc.add(new ConfigChangeEvent(ConfigKey.preferedTheme, Themer.customThemeCode))}
|
|
82
|
-
preview={<CustomThemePreview theme={Themer.customTheme} />}
|
|
83
|
-
/>
|
|
84
|
-
)}
|
|
85
|
-
{Themes.list().map((item) => (
|
|
86
|
-
<ThemeOption
|
|
65
|
+
{largeurGrille > 0 &&
|
|
66
|
+
Themes.list().map((item) => {
|
|
67
|
+
const choisi = currentTheme === item;
|
|
68
|
+
return (
|
|
69
|
+
<Pressable
|
|
87
70
|
key={item}
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
71
|
+
accessibilityRole="button"
|
|
72
|
+
accessibilityState={{ selected: choisi }}
|
|
73
|
+
disabled={choisi}
|
|
74
|
+
onPress={() => configBloc.add(new ConfigChangeEvent(ConfigKey.preferedTheme, item))}
|
|
75
|
+
style={[styles.item, { width: largeur }]}
|
|
76
|
+
>
|
|
77
|
+
{/* Aperçu, entouré quand il est choisi */}
|
|
78
|
+
<View style={[styles.cadre, { borderColor: choisi ? theme.colorScheme.primary : 'transparent' }]}>
|
|
79
|
+
<Image
|
|
80
|
+
source={themeIcon(item)}
|
|
81
|
+
style={[styles.apercu, { backgroundColor: theme.colorScheme.surface }]}
|
|
82
|
+
contentFit="cover"
|
|
83
|
+
/>
|
|
84
|
+
</View>
|
|
85
|
+
{choisi && (
|
|
86
|
+
<View style={[styles.coche, { backgroundColor: theme.colorScheme.primary, borderColor: theme.colorScheme.surface }]}>
|
|
87
|
+
<MaterialIcons name="check" size={14} color={theme.colorScheme.onPrimary} />
|
|
88
|
+
</View>
|
|
89
|
+
)}
|
|
90
|
+
<Text
|
|
91
|
+
style={[
|
|
92
|
+
theme.textTheme.displayMedium,
|
|
93
|
+
styles.libelle,
|
|
94
|
+
{ fontWeight: choisi ? '700' : '500' },
|
|
95
|
+
choisi ? null : { color: Themer.neural03Color },
|
|
96
|
+
]}
|
|
97
|
+
>
|
|
98
|
+
{themeTitle(traductions, item)}
|
|
99
|
+
</Text>
|
|
100
|
+
</Pressable>
|
|
101
|
+
);
|
|
102
|
+
})}
|
|
103
|
+
</View>
|
|
104
|
+
</Card>
|
|
105
|
+
|
|
106
|
+
{/* Couleur d'accentuation */}
|
|
107
|
+
<View style={styles.espace} />
|
|
108
|
+
<ProfileSectionTitre titre={traductions.appSettingPageAccentSection} />
|
|
109
|
+
<Card style={styles.card}>
|
|
110
|
+
<View style={styles.pastilles}>
|
|
111
|
+
{[
|
|
112
|
+
// Couleur du thème personnalisé de l'hôte, en tête
|
|
113
|
+
...(Themer.hasCustomTheme ? [Themer.customAccentCode] : []),
|
|
114
|
+
...Accents.list(),
|
|
115
|
+
].map((accent) => {
|
|
116
|
+
const apercu = Themer.get(sombre ? Themes.dark : Themes.light, accent).colorScheme;
|
|
117
|
+
const teintes = { accent: apercu.primary, surAccent: apercu.onPrimary };
|
|
118
|
+
const choisi = currentAccent === accent;
|
|
119
|
+
return (
|
|
120
|
+
<Pressable
|
|
121
|
+
key={accent}
|
|
122
|
+
accessibilityRole="button"
|
|
123
|
+
accessibilityLabel={Themer.accentLabel(traductions, accent)}
|
|
124
|
+
accessibilityState={{ selected: choisi }}
|
|
125
|
+
disabled={choisi}
|
|
126
|
+
onPress={() => configBloc.add(new ConfigChangeEvent(ConfigKey.preferedAccent, accent))}
|
|
127
|
+
style={styles.accent}
|
|
128
|
+
>
|
|
129
|
+
{/* Pastille, cochée quand elle est choisie */}
|
|
130
|
+
<View style={[styles.anneau, { borderColor: choisi ? theme.colorScheme.onSurface : 'transparent' }]}>
|
|
131
|
+
<View style={[styles.pastille, { backgroundColor: teintes.accent }]}>
|
|
132
|
+
{choisi && <MaterialIcons name="check" size={22} color={teintes.surAccent} />}
|
|
133
|
+
</View>
|
|
134
|
+
</View>
|
|
135
|
+
<Text
|
|
136
|
+
numberOfLines={1}
|
|
137
|
+
style={[
|
|
138
|
+
theme.textTheme.displaySmall,
|
|
139
|
+
styles.libelle,
|
|
140
|
+
{ fontWeight: choisi ? '700' : '400' },
|
|
141
|
+
{ color: choisi ? theme.colorScheme.onSurface : Themer.neural03Color },
|
|
142
|
+
]}
|
|
143
|
+
>
|
|
144
|
+
{Themer.accentLabel(traductions, accent)}
|
|
145
|
+
</Text>
|
|
146
|
+
</Pressable>
|
|
147
|
+
);
|
|
148
|
+
})}
|
|
97
149
|
</View>
|
|
98
150
|
</Card>
|
|
99
151
|
</ScrollView>
|
|
@@ -102,113 +154,18 @@ export function ProfileParametrePageTheme() {
|
|
|
102
154
|
);
|
|
103
155
|
}
|
|
104
156
|
|
|
105
|
-
/** Une option de thème : aperçu, entouré et coché quand il est choisi, puis son nom */
|
|
106
|
-
function ThemeOption({
|
|
107
|
-
largeur,
|
|
108
|
-
title,
|
|
109
|
-
selected,
|
|
110
|
-
onSelect,
|
|
111
|
-
preview,
|
|
112
|
-
}: {
|
|
113
|
-
largeur: number;
|
|
114
|
-
title: string;
|
|
115
|
-
selected: boolean;
|
|
116
|
-
onSelect: () => void;
|
|
117
|
-
preview: ReactNode;
|
|
118
|
-
}) {
|
|
119
|
-
const theme = useTheme();
|
|
120
|
-
return (
|
|
121
|
-
<Pressable
|
|
122
|
-
accessibilityRole="button"
|
|
123
|
-
accessibilityState={{ selected }}
|
|
124
|
-
disabled={selected}
|
|
125
|
-
onPress={onSelect}
|
|
126
|
-
style={[styles.item, { width: largeur }]}
|
|
127
|
-
>
|
|
128
|
-
{/* Aperçu, entouré quand il est choisi */}
|
|
129
|
-
<View style={[styles.cadre, { borderColor: selected ? theme.colorScheme.primary : 'transparent' }]}>
|
|
130
|
-
<View style={[styles.apercu, { backgroundColor: theme.colorScheme.surface }]}>{preview}</View>
|
|
131
|
-
</View>
|
|
132
|
-
{selected && (
|
|
133
|
-
<View style={[styles.coche, { backgroundColor: theme.colorScheme.primary, borderColor: theme.colorScheme.surface }]}>
|
|
134
|
-
<MaterialIcons name="check" size={14} color={theme.colorScheme.onPrimary} />
|
|
135
|
-
</View>
|
|
136
|
-
)}
|
|
137
|
-
<Text
|
|
138
|
-
style={[
|
|
139
|
-
theme.textTheme.displayMedium,
|
|
140
|
-
styles.libelle,
|
|
141
|
-
{ fontWeight: selected ? '700' : '500' },
|
|
142
|
-
selected ? null : { color: Themer.neural03Color },
|
|
143
|
-
]}
|
|
144
|
-
>
|
|
145
|
-
{title}
|
|
146
|
-
</Text>
|
|
147
|
-
</Pressable>
|
|
148
|
-
);
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
/**
|
|
152
|
-
* Aperçu du thème personnalisé de l'hôte (pas d'image comme pour les
|
|
153
|
-
* thèmes du SDK) : une miniature d'accueil dessinée avec ses couleurs.
|
|
154
|
-
*/
|
|
155
|
-
function CustomThemePreview({ theme }: { theme: ThemeData }) {
|
|
156
|
-
const primary = theme.colorScheme.primary;
|
|
157
|
-
const secondary = theme.colorScheme.secondary;
|
|
158
|
-
const bar = (width: number, color: string) => <View style={[styles.bar, { width, backgroundColor: color }]} />;
|
|
159
|
-
return (
|
|
160
|
-
<View style={[styles.flex, styles.mock, { backgroundColor: theme.scaffoldBackgroundColor }]}>
|
|
161
|
-
{/* Avatar et titre */}
|
|
162
|
-
<View style={styles.mockRow}>
|
|
163
|
-
<View style={[styles.dot16, { backgroundColor: secondary }]} />
|
|
164
|
-
{bar(40, Themer.neural02Color)}
|
|
165
|
-
</View>
|
|
166
|
-
<View style={styles.gap12} />
|
|
167
|
-
{/* Carte du compte */}
|
|
168
|
-
<View style={[styles.mockCard, { backgroundColor: theme.cardColor }]}>
|
|
169
|
-
{bar(50, Themer.neural02Color)}
|
|
170
|
-
{bar(30, primary)}
|
|
171
|
-
</View>
|
|
172
|
-
<View style={styles.gap12} />
|
|
173
|
-
{/* Boutons d'action */}
|
|
174
|
-
<View style={styles.mockActions}>
|
|
175
|
-
{[0, 1, 2].map((i) => (
|
|
176
|
-
<View key={i} style={[styles.mockButton, { backgroundColor: primary }]} />
|
|
177
|
-
))}
|
|
178
|
-
</View>
|
|
179
|
-
<View style={styles.gap14} />
|
|
180
|
-
{/* Liste */}
|
|
181
|
-
{[0, 1, 2].map((i) => (
|
|
182
|
-
<View key={i} style={[styles.mockRow, styles.mockListRow]}>
|
|
183
|
-
<View style={[styles.dot14, { backgroundColor: secondary }]} />
|
|
184
|
-
{bar(46, Themer.neural02Color)}
|
|
185
|
-
</View>
|
|
186
|
-
))}
|
|
187
|
-
</View>
|
|
188
|
-
);
|
|
189
|
-
}
|
|
190
|
-
|
|
191
|
-
const ESPACE = 12;
|
|
192
|
-
|
|
193
157
|
const styles = StyleSheet.create({
|
|
194
|
-
flex: { flex: 1 },
|
|
195
|
-
mock: { padding: 10 },
|
|
196
|
-
mockRow: { flexDirection: 'row', alignItems: 'center', gap: 6 },
|
|
197
|
-
mockListRow: { marginBottom: 8 },
|
|
198
|
-
mockCard: { height: 54, padding: 8, borderRadius: 8, justifyContent: 'space-between' },
|
|
199
|
-
mockActions: { flexDirection: 'row', justifyContent: 'space-between' },
|
|
200
|
-
mockButton: { width: 26, height: 26, borderRadius: 8 },
|
|
201
|
-
bar: { height: 6, borderRadius: 3 },
|
|
202
|
-
dot16: { width: 16, height: 16, borderRadius: 8 },
|
|
203
|
-
dot14: { width: 14, height: 14, borderRadius: 7 },
|
|
204
|
-
gap12: { height: 12 },
|
|
205
|
-
gap14: { height: 14 },
|
|
206
158
|
contenu: { paddingTop: 8, paddingBottom: 16 },
|
|
207
159
|
card: { margin: 0 },
|
|
208
|
-
grille: { padding: 14, flexDirection: 'row', flexWrap: 'wrap', columnGap:
|
|
160
|
+
grille: { padding: 14, flexDirection: 'row', flexWrap: 'wrap', columnGap: 12, rowGap: 16 },
|
|
209
161
|
item: { alignItems: 'center' },
|
|
210
162
|
cadre: { alignSelf: 'stretch', padding: 3, borderWidth: 2, borderRadius: 14 },
|
|
211
|
-
apercu: { width: '100%', aspectRatio: 0.6, borderRadius: 10
|
|
163
|
+
apercu: { width: '100%', aspectRatio: 0.6, borderRadius: 10 },
|
|
212
164
|
coche: { position: 'absolute', top: 8, right: 8, borderRadius: 12, borderWidth: 2, padding: 1 },
|
|
213
165
|
libelle: { marginTop: 8, textAlign: 'center' },
|
|
166
|
+
espace: { height: 24 },
|
|
167
|
+
pastilles: { paddingHorizontal: 10, paddingVertical: 16, flexDirection: 'row', flexWrap: 'wrap', justifyContent: 'space-evenly', rowGap: 16 },
|
|
168
|
+
accent: { width: 64, alignItems: 'center' },
|
|
169
|
+
anneau: { padding: 3, borderWidth: 2, borderRadius: 26 },
|
|
170
|
+
pastille: { width: 40, height: 40, borderRadius: 20, alignItems: 'center', justifyContent: 'center' },
|
|
214
171
|
});
|