Salīdzināt revīzijas

...

23 commits

Autors SHA1 Ziņojums Datums
docjyJ
133df5bdb7 Update Lang 2020-09-03 12:01:05 +02:00
docjyJ
c6bb1ccc86 Update About Screen 2020-09-03 12:01:05 +02:00
docjyJ
3ff5a40f8d Add Thanks key 2020-09-03 12:01:05 +02:00
docjyJ
955eb11b84 Update Screen 2020-09-03 12:01:05 +02:00
docjyJ
47e749b528 Update Lang 2020-09-03 12:01:05 +02:00
docjyJ
2f94be64e5 Update Options Dialog to support Icon 2020-09-03 12:01:05 +02:00
docjyJ
a9a2b9150b Update About Screen 2020-09-03 12:01:05 +02:00
docjyJ
a8b9fd49b7 Add Thanks key 2020-09-03 12:00:59 +02:00
docjyJ
2ed4fbd780 Add Thaks card 2020-09-03 12:00:59 +02:00
43cf7dc874 Merge branch 'AdaptativeIcon' 2020-09-03 11:36:03 +02:00
docjyJ
45f42902bc Add android.icon in assets 2020-09-01 16:45:53 +02:00
docjyJ
52fd1e943f Update with new color 2020-09-01 16:33:11 +02:00
09942b2fc5 Merge branch 'French_language' of leban/application-amicale into master 2020-09-01 15:13:48 +02:00
Gérald L
9b26d045b3 Fix typos - Missing spaces 2020-08-31 21:21:06 +02:00
docjyJ
e1bae05929 Update path of icon notification 2020-08-30 13:38:15 +02:00
docjyJ
de98364082 Add new icon 2020-08-30 10:51:51 +02:00
docjyJ
973510fac0 Delete old icon 2020-08-30 10:48:21 +02:00
f5c043dd7d Bump version code 2020-08-26 11:27:27 +02:00
ea7321eb9d Fix planning management to match new api 2020-08-26 10:14:44 +02:00
dafd454a42 Fix locale 2020-08-25 19:01:23 +02:00
0dae9c08b5 Improve mascot size 2020-08-25 18:55:46 +02:00
d38f11d45f Fix mascot size on thinner displays 2020-08-25 18:41:40 +02:00
5a98f5506a Improve translation and start/feedback screen 2020-08-23 19:57:54 +02:00
37 mainīti faili ar 537 papildinājumiem un 317 dzēšanām

Parādīt failu

@ -148,7 +148,7 @@ android {
applicationId 'fr.amicaleinsat.application'
minSdkVersion rootProject.ext.minSdkVersion
targetSdkVersion rootProject.ext.targetSdkVersion
versionCode 41
versionCode 42
versionName "4.0.1"
missingDimensionStrategy 'react-native-camera', 'general'
}

Bināro failu nav iespējams attēlot.

Pēc

Platums:  |  Augstums:  |  Izmērs: 28 KiB

Parādīt failu

@ -0,0 +1,35 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108"
android:autoMirrored="true"
tools:ignore="VectorRaster">
<group android:scaleX="0.9327526"
android:scaleY="0.9327526"
android:translateX="-9.18"
android:translateY="-9.18">
<path
android:pathData="m66.726,45.46 l20.999,26.022 0.539,-27.06 84.903,83.371 -42.449,44.716 -83.531,-81.39z" android:strokeAlpha="0">
<aapt:attr name="android:fillColor">
<gradient
android:startY="60"
android:startX="60"
android:endY="100"
android:endX="100"
android:type="linear">
<item
android:color="#22000000"
android:offset="0.0" />
<item
android:color="#00000000"
android:offset="1.0" />
</gradient>
</aapt:attr>
</path>
<path android:fillColor="#fff"
android:pathData="m66.678,45.377 l19.491,45.744h-38.982zM76.093,44.347h12.186v31.47z" android:strokeAlpha="0"/>
</group>
</vector>

Parādīt failu

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

Parādīt failu

@ -0,0 +1,5 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@color/ic_launcher_background"/>
<foreground android:drawable="@drawable/ic_launcher_foreground"/>
</adaptive-icon>

Parādīt failu

@ -0,0 +1,17 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="24dp"
android:height="24dp"
android:viewportWidth="24"
android:viewportHeight="24"
android:tint="#FFFFFF">
<group android:scaleX="0.12773363"
android:scaleY="0.12773363"
android:translateX="3.3479624"
android:translateY="3.3479624">
<path
android:pathData="m64.695,3.346 l56.134,131.74h-112.27zM91.81,0.379h35.096v90.634z"
android:strokeAlpha="0"
android:strokeWidth="2.88"
android:fillColor="#fff"/>
</group>
</vector>

Bināro failu nav iespējams attēlot.

Pirms

Platums:  |  Augstums:  |  Izmērs: 3,4 KiB

Pēc

Platums:  |  Augstums:  |  Izmērs: 2,1 KiB

Bināro failu nav iespējams attēlot.

Pirms

Platums:  |  Augstums:  |  Izmērs: 5 KiB

Pēc

Platums:  |  Augstums:  |  Izmērs: 3,9 KiB

Bināro failu nav iespējams attēlot.

Pirms

Platums:  |  Augstums:  |  Izmērs: 1,2 KiB

Pēc

Platums:  |  Augstums:  |  Izmērs: 478 B

Bināro failu nav iespējams attēlot.

Pirms

Platums:  |  Augstums:  |  Izmērs: 1,9 KiB

Pēc

Platums:  |  Augstums:  |  Izmērs: 1,5 KiB

Bināro failu nav iespējams attēlot.

Pirms

Platums:  |  Augstums:  |  Izmērs: 2,7 KiB

Pēc

Platums:  |  Augstums:  |  Izmērs: 2,5 KiB

Bināro failu nav iespējams attēlot.

Pirms

Platums:  |  Augstums:  |  Izmērs: 823 B

Pēc

Platums:  |  Augstums:  |  Izmērs: 340 B

Bināro failu nav iespējams attēlot.

Pirms

Platums:  |  Augstums:  |  Izmērs: 4,4 KiB

Pēc

Platums:  |  Augstums:  |  Izmērs: 2,8 KiB

Bināro failu nav iespējams attēlot.

Pirms

Platums:  |  Augstums:  |  Izmērs: 6,7 KiB

Pēc

Platums:  |  Augstums:  |  Izmērs: 5,5 KiB

Bināro failu nav iespējams attēlot.

Pirms

Platums:  |  Augstums:  |  Izmērs: 1,6 KiB

Pēc

Platums:  |  Augstums:  |  Izmērs: 674 B

Bināro failu nav iespējams attēlot.

Pirms

Platums:  |  Augstums:  |  Izmērs: 7,8 KiB

Pēc

Platums:  |  Augstums:  |  Izmērs: 4,3 KiB

Bināro failu nav iespējams attēlot.

Pirms

Platums:  |  Augstums:  |  Izmērs: 12 KiB

Pēc

Platums:  |  Augstums:  |  Izmērs: 8,7 KiB

Bināro failu nav iespējams attēlot.

Pirms

Platums:  |  Augstums:  |  Izmērs: 2,4 KiB

Pēc

Platums:  |  Augstums:  |  Izmērs: 969 B

Bināro failu nav iespējams attēlot.

Pirms

Platums:  |  Augstums:  |  Izmērs: 10 KiB

Pēc

Platums:  |  Augstums:  |  Izmērs: 6 KiB

Bināro failu nav iespējams attēlot.

Pirms

Platums:  |  Augstums:  |  Izmērs: 16 KiB

Pēc

Platums:  |  Augstums:  |  Izmērs: 13 KiB

Bināro failu nav iespējams attēlot.

Pirms

Platums:  |  Augstums:  |  Izmērs: 3,2 KiB

Parādīt failu

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#C32733</color>
</resources>

Bināro failu nav iespējams attēlot.

Pirms

Platums:  |  Augstums:  |  Izmērs: 9,5 KiB

Pēc

Platums:  |  Augstums:  |  Izmērs: 6 KiB

Binārs
assets/android.icon.round.png Parasts fails

Bināro failu nav iespējams attēlot.

Pēc

Platums:  |  Augstums:  |  Izmērs: 13 KiB

Parādīt failu

@ -128,7 +128,7 @@
"noGroupSelected": "No group selected. Please select your group using the big beautiful red button bellow.",
"favorites": "Favorites",
"mascotDialog": {
"title": "Skipping classes is bad",
"title": "Don't skip class",
"message": "Here is Planex! You can set your class and your crush's to favorites in order to find them back easily!\n\nIf you mainly use Campus for Planex, go to the settings to make the app directly start on it!",
"ok": "Settings",
"cancel": "Later"
@ -346,23 +346,32 @@
"license": "License",
"debug": "Debug",
"team": "Team",
"author": "Author and maintainer",
"authorMail": "Send an email",
"additionalDev": "Thanks",
"technologies": "Technologies",
"reactNative": "Made with React Native",
"libs": "Libraries used"
"libs": "Libraries used",
"thanks": "Thanks",
"user": {
"youName": "You",
"you": "[NON TRADUIT] Toi aussi devient le prochaint dévelopeur à rejoindre la team, passe voir le git de l'application y'a tout plein d'info",
"arnaud": "[NON TRADUIT] Étudiant en IR (2020). C'est le créateur de cette magnifique application que t'utilise tout les jour. Et il est vraiment BG aussi.",
"yohan": "[NON TRADUIT] Étudiant en [Je sais pas quoi] (2020). Il nous aide à corriger les bug. Et j'imagine aussi qu'il est BG mais je le connait pas.",
"beranger": "[NON TRADUIT] Étudiant en AE (2020) et Président de lAmicale au moment de la création et du lancement du projet. Lapplication, cétait son idée. Il a beaucoup aidé pour trouver des bugs, de nouvelles fonctionnalités et faire de la com.",
"celine": "[NON TRADUIT] Étudiante en GPE (2020). Sans elle, tout serait moins mignon. Elle a aidé pour écrire le texte, faire de la com, et aussi à créer la mascotte 🦊.",
"damien": "[NON TRADUIT] Étudiant en IR (2020) et créateur de la dernière version du site de lAmicale. Grâce à son aide, intégrer les services de lAmicale à lapplication a été très simple.",
"titouan": "[NON TRADUIT] Étudiant en IR (2020). Il a beaucoup aidé pour trouver des bugs et proposer des nouvelles fonctionnalités.",
"theo": "[NON TRADUIT] Étudiant en AE (2020). Si lapplication marche sur iOS, cest grâce à son aide lors de ses nombreux tests."
}
},
"feedback": {
"title": "Feedback",
"bugs": "Report Bugs",
"bugsSubtitle": "Did you find a bug? Let us know!",
"bugsDescription": "Reporting bugs helps us make the app better. To do so, use one of the buttons below and be as precise as possible when describing your problem!",
"feedbackSubtitle": "Let us know what you think!",
"feedbackDescription": "Do you have a feature you want to be added/changed/removed, want to give your opinion on the app or simply chat with the dev? Use one of the links below!",
"contactMeans": "Using Gitea is recommended, to use it simply login with your INSA account.",
"homeButtonTitle": "Feedback/Bug report",
"homeButtonSubtitle": "Contact the devs"
"title": "Contribute",
"feedback": "Contact the dev",
"feedbackSubtitle": "A student like you!",
"feedbackDescription": "Feedback or bugs, you are always welcome.\nChoose your preferred way from the buttons bellow.",
"contribute": "Contribute to the project",
"contributeSubtitle": "With a possible \"implication citoyenne\"!",
"contributeDescription": "Everyone can help: communication, design or coding! You are free to contribute as you like.\nYou can find bellow a link to Trello for project organization, and a link to the source code on GitEtud.",
"homeButtonTitle": "Contribute to the project",
"homeButtonSubtitle": "Your help is important"
},
"game": {
"title": "So Awesome Game",
@ -413,16 +422,16 @@
"text": "You can do much more with CAMPUS, but I can't explain everything here. Explore the app to find out!"
},
"slideDone": {
"title": "Your feedback is valuable!",
"text": "This app is the work of one student (with some help here and there), so your feedback is much appreciated!"
"title": "Contribute to the project!",
"text": "This app is the work of one student, so your feedback and your help are welcome!\nEveryone can help: communication, design or coding!"
},
"updateSlide0": {
"title": "New in this update!",
"text": "Hello you! I'm here to help you around the app."
"title": "Hi you!",
"text": "I'm new here and I will help you around the app. My thing is to give you lots of tips and tricks."
},
"updateSlide1": {
"title": "Contribute!",
"text": "Everyone is free to contribute to the project, from reporting bugs to implementing new features"
"title": "Contribute to the project!",
"text": "This app is the work of one student, so your feedback and your help are welcome!\nEveryone can help: communication, design or coding!"
},
"aprilFoolsSlide": {
"title": "New in this update!",

Parādīt failu

@ -50,7 +50,7 @@
"paymentMethods": "Moyens de Paiement",
"paymentMethodsDescription": "Toute monnaie jusqu'à 10€.\nCarte bancaire acceptée.",
"washerProcedure": "Déposer le linge dans le tambour sans le tasser et en respectant les charges.\n\nFermer la porte de l'appareil.\n\nSélectionner un programme avec l'une des quatre touches de programme favori standard.\n\nAprès avoir payé à la centrale de commande, appuyer sur le bouton marqué START du lave-linge.\n\nDès que le programme est terminé, lafficheur indique 'Programme terminé', appuyer sur le bouton jaune douverture du hublot pour récupérer le linge.",
"washerTips": "Programme blanc/couleur : 6kg de linge sec (textiles en coton, lin, linge de corps, draps, jeans,serviettes de toilettes).\n\nProgramme nonrepassable : 3,5 kg de linge sec (textiles en fibres synthétiques, cotonet polyester mélangés).\n\nProgramme fin 30°C : 2,5 kg de linge sec (textiles délicats en fibres synthétiques, rayonne).\n\nProgramme laine 30°C : 2,5 kg de linge sec (textiles en laine et lainages lavables).",
"washerTips": "Programme blanc/couleur : 6kg de linge sec (textiles en coton, lin, linge de corps, draps, jeans,serviettes de toilettes).\n\nProgramme non repassable : 3,5 kg de linge sec (textiles en fibres synthétiques, coton et polyester mélangés).\n\nProgramme fin 30°C : 2,5 kg de linge sec (textiles délicats en fibres synthétiques, rayonne).\n\nProgramme laine 30°C : 2,5 kg de linge sec (textiles en laine et lainages lavables).",
"dryerProcedure": "Déposer le linge dans le tambour sans le tasser et en respectant les charges.\n\nFermer la porte de l'appareil.\n\nSélectionner un programme avec l'une des quatre touches de programme favori standard.\n\nAprès avoir payé à la centrale de commande, appuyer sur le bouton marqué START du lave-linge.",
"dryerTips": "La durée conseillée est de 35 minutes pour 14kg de linge. Vous pouvez choisir une durée plus courte si le sèche-linge n'est pas chargé.",
"procedure": "Procédure",
@ -345,23 +345,32 @@
"license": "Licence",
"debug": "Debug",
"team": "Équipe",
"author": "Auteur et mainteneur",
"authorMail": "Envoyer un mail",
"additionalDev": "Remerciements",
"technologies": "Technologies",
"reactNative": "Créé avec React Native",
"libs": "Librairies utilisées"
"libs": "Librairies utilisées",
"thanks": "Remerciements",
"user": {
"youName": "Toi",
"you": "Toi aussi devient le prochaint dévelopeur à rejoindre la team, passe voir le git de l'application y'a tout plein d'info",
"arnaud": "Étudiant en IR (2020). C'est le créateur de cette magnifique application que t'utilise tout les jour. Et il est vraiment BG aussi.",
"yohan": "Étudiant en [Je sais pas quoi] (2020). Il nous aide à corriger les bug. Et j'imagine aussi qu'il est BG mais je le connait pas.",
"beranger": "Étudiant en AE (2020) et Président de lAmicale au moment de la création et du lancement du projet. Lapplication, cétait son idée. Il a beaucoup aidé pour trouver des bugs, de nouvelles fonctionnalités et faire de la com.",
"celine": "Étudiante en GPE (2020). Sans elle, tout serait moins mignon. Elle a aidé pour écrire le texte, faire de la com, et aussi à créer la mascotte 🦊.",
"damien": "Étudiant en IR (2020) et créateur de la dernière version du site de lAmicale. Grâce à son aide, intégrer les services de lAmicale à lapplication a été très simple.",
"titouan": "Étudiant en IR (2020). Il a beaucoup aidé pour trouver des bugs et proposer des nouvelles fonctionnalités.",
"theo": "Étudiant en AE (2020). Si lapplication marche sur iOS, cest grâce à son aide lors de ses nombreux tests."
}
},
"feedback": {
"title": "Feedback",
"bugs": "Rapporter des Bugs",
"bugsSubtitle": "Tu as trouvé un bug ?",
"bugsDescription": "Rapporter les bugs m'aide à améliorer l'appli. Pour cela, merci d'utiliser un des boutons ci-dessous et de décrire ton problème le plus précisément possible !",
"feedbackSubtitle": "Dis moi ce que tu penses !",
"feedbackDescription": "Tu veux voir une fonctionnalité ajoutée/modifiée/supprimée ? Tu veux donner ton opinion sur l'appli ou simplement discuter avec le développeur (c'est moi coucou) ? Utilise un des liens ci-dessous !",
"contactMeans": "L'utilisation de Gitea est recommandée, pour l'utiliser, connecte toi avec tes identifiants INSA.",
"homeButtonTitle": "Feedback/Bugs",
"homeButtonSubtitle": "Contacte le développeur de l'appli"
"title": "Participer",
"feedback": "Contacte le développeur",
"feedbackSubtitle": "C'est un étudiant comme toi !",
"feedbackDescription": "Que ce soit pour donner ton avis ou rapporter des bugs, tu es le bienvenue.\nUtilise le moyen de ton choix parmi les boutons ci-dessous.",
"contribute": "Contribue au projet",
"contributeSubtitle": "Avec une possible implication citoyenne !",
"contributeDescription": "Il y en a pour tous les goûts : de la com', du design ou de la technique. Tu es libre de participer comme tu veux.\nTu trouveras ci-dessous un Trello de l'organisation du projet, ainsi que le code source sur GitEtud.",
"homeButtonTitle": "Participer au projet",
"homeButtonSubtitle": "Ton aide compte"
},
"game": {
"title": "Jeu trop ouf",
@ -412,16 +421,16 @@
"text": "Tu peux faire bien plus avec CAMPUS, mais je n'ai pas le temps de tout dire ici. Balade toi sur l'appli pour tout découvrir !"
},
"slideDone": {
"title": "Ton avis compte !",
"text": "Cette appli à été réalisée par un seul étudiant (avec un peu d'aide par-ci par-là), donc tes retours sont les bienvenus !"
"title": "Participe au projet !",
"text": "Cette appli à été réalisée par un seul étudiant, donc tes retours et ton aide sont les bienvenus !\nIl y en a pour tous les goûts : de la com', du design ou de la technique !"
},
"updateSlide0": {
"title": "Nouveau dans cette mise à jour !",
"text": "Coucou toi ! Je suis là pour t'aider trouver à utiliser l'appli."
"title": "Coucou toi !",
"text": "Je suis le petit nouveau qui t'accompagnera sur l'appli. Mon dada c'est de te donner plein d'astuces et d'infos."
},
"updateSlide1": {
"title": "Participe au projet !",
"text": "Tout le monde peut participer, que ce soit pour trouver des bugs ou ajouter des nouvelles fonctionnalités."
"text": "Cette appli à été réalisée par un seul étudiant, donc tes retours et ton aide sont les bienvenus !\nIl y en a pour tous les goûts : de la com', du design ou de la technique !"
},
"aprilFoolsSlide": {
"title": "Nouveau dans cette mise à jour !",

Parādīt failu

@ -6,6 +6,7 @@ import {FlatList} from 'react-native';
export type OptionsDialogButtonType = {
title: string,
icon?: string,
onPress: () => void,
};
@ -19,10 +20,19 @@ type PropsType = {
class OptionsDialog extends React.PureComponent<PropsType> {
getButtonRender = ({item}: {item: OptionsDialogButtonType}): React.Node => {
return <Button onPress={item.onPress}>{item.title}</Button>;
return (
<Button onPress={item.onPress} icon={item.icon}>
{item.title}
</Button>
);
};
keyExtractor = (item: OptionsDialogButtonType): string => item.title;
keyExtractor = (item: OptionsDialogButtonType): string => {
if (item.icon != null) {
return item.title + item.icon;
}
return item.title;
};
render(): React.Node {
const {props} = this;

Parādīt failu

@ -4,12 +4,12 @@ import * as React from 'react';
import {StyleSheet, View} from 'react-native';
import i18n from 'i18n-js';
import {Avatar, Button, Card, TouchableRipple} from 'react-native-paper';
import {getFormattedEventTime, isDescriptionEmpty} from '../../utils/Planning';
import {getTimeOnlyString, isDescriptionEmpty} from '../../utils/Planning';
import CustomHTML from '../Overrides/CustomHTML';
import type {EventType} from '../../screens/Home/HomeScreen';
import type {PlanningEventType} from '../../utils/Planning';
type PropsType = {
event?: EventType | null,
event?: PlanningEventType | null,
clickAction: () => void,
};
@ -62,19 +62,13 @@ class PreviewEventDashboardItem extends React.Component<PropsType> {
{hasImage ? (
<Card.Title
title={event.title}
subtitle={getFormattedEventTime(
event.date_begin,
event.date_end,
)}
subtitle={getTimeOnlyString(event.date_begin)}
left={getImage}
/>
) : (
<Card.Title
title={event.title}
subtitle={getFormattedEventTime(
event.date_begin,
event.date_end,
)}
subtitle={getTimeOnlyString(event.date_begin)}
/>
)}
{!isEmpty ? (

Parādīt failu

@ -24,7 +24,7 @@ class MascotIntroEnd extends React.Component<null> {
<Mascot
style={{
...styles.center,
height: '80%',
width: '80%',
}}
emotion={MASCOT_STYLE.COOL}
animated

Parādīt failu

@ -26,7 +26,7 @@ class MascotIntroWelcome extends React.Component<null> {
<Mascot
style={{
...styles.center,
height: '80%',
width: '80%',
}}
emotion={MASCOT_STYLE.NORMAL}
animated

Parādīt failu

@ -1,17 +1,20 @@
// @flow
import * as React from 'react';
import {FlatList, Linking, Platform, Image} from 'react-native';
import {FlatList, Linking, Platform, Image, View} from 'react-native';
import i18n from 'i18n-js';
import {Avatar, Card, List, Title, withTheme} from 'react-native-paper';
import {Avatar, Card, List, withTheme} from 'react-native-paper';
import {StackNavigationProp} from '@react-navigation/stack';
import {Modalize} from "react-native-modalize";
import packageJson from '../../../package.json';
import CollapsibleFlatList from '../../components/Collapsible/CollapsibleFlatList';
import APP_LOGO from '../../../assets/android.icon.png';
import APP_LOGO from '../../../assets/android.icon.round.png';
import type {
CardTitleIconPropsType,
ListIconPropsType,
} from '../../constants/PaperStyles';
import OptionsDialog from "../../components/Dialogs/OptionsDialog";
import type {OptionsDialogButtonType} from "../../components/Dialogs/OptionsDialog";
type ListItemType = {
onPressCallback: () => void,
@ -20,6 +23,14 @@ type ListItemType = {
showChevron: boolean,
};
type AthorsItemType = {
name: string,
message: string,
btnTrool: OptionsDialogButtonType,
btnLinkedin: OptionsDialogButtonType,
btnMail: OptionsDialogButtonType,
};
const links = {
appstore: 'https://apps.apple.com/us/app/campus-amicale-insat/id1477722148',
playstore:
@ -30,13 +41,13 @@ const links = {
'https://git.etud.insa-toulouse.fr/vergnet/application-amicale/src/branch/master/Changelog.md',
license:
'https://git.etud.insa-toulouse.fr/vergnet/application-amicale/src/branch/master/LICENSE',
authorMail:
arnaudMail:
'mailto:vergnet@etud.insa-toulouse.fr?' +
'subject=' +
'Application Amicale INSA Toulouse' +
'&body=' +
'Coucou !\n\n',
authorLinkedin: 'https://www.linkedin.com/in/arnaud-vergnet-434ba5179/',
arnaudLinkedin: 'https://www.linkedin.com/in/arnaud-vergnet-434ba5179/',
yohanMail:
'mailto:ysimard@etud.insa-toulouse.fr?' +
'subject=' +
@ -64,6 +75,101 @@ function openWebLink(link: string) {
* Class defining an about screen. This screen shows the user information about the app and it's author.
*/
class AboutScreen extends React.Component<PropsType> {
modalRef: Modalize | null;
/**
* Data team
*/
teamUsers = {
arnaud: {
name: 'Arnaud VERGNET',
message: 'C vrément tro 1 bg !!',
icon: 'account-circle',
btnTrool: {
title: 'SWAG',
onPress: () => {
openWebLink(links.meme);
},
},
btnLinkedin: {
title: 'Linkedin',
onPress: () => {
openWebLink(links.arnaudMail);
},
},
btnMail: {
title: i18n.t('screens.about.authorMail'),
onPress: () => {
openWebLink(links.arnaudLinkedin);
},
},
},
yohan: {
name: 'Yohan Simard',
message: 'Correction de quelques bugs',
icon: 'account-circle',
btnTrool: null,
btnLinkedin: {
title: 'Linkedin',
onPress: () => {
openWebLink(links.yohanLinkedin);
},
},
btnMail: {
title: i18n.t('screens.about.authorMail'),
onPress: () => {
openWebLink(links.yohanMail);
},
},
},
};
/**
* Data thanks
*/
thanksUsers = {
beranger: {
name: 'Béranger Quintana Y Arciosana',
message: 'Étudiant en AE (2020) et Président de lAmicale au moment de la création et du lancement du projet. Lapplication, cétait son idée. Il a beaucoup aidé pour trouver des bugs, de nouvelles fonctionnalités et faire de la com.',
icon: 'account-circle',
btnTrool: null,
btnLinkedin: null,
btnMail: null,
},
celine: {
name: 'Céline Tassin',
message: 'Étudiante en GPE (2020). Sans elle, tout serait moins mignon. Elle a aidé pour écrire le texte, faire de la com, et aussi à créer la mascotte 🦊.',
icon: 'account-circle',
btnTrool: null,
btnLinkedin: null,
btnMail: null,
},
damien: {
name: 'Damien Molina',
message: 'Étudiant en IR (2020) et créateur de la dernière version du site de lAmicale. Grâce à son aide, intégrer les services de lAmicale à lapplication a été très simple.',
icon: 'account-circle',
btnTrool: null,
btnLinkedin: null,
btnMail: null,
},
titouan: {
name: 'Titouan Labourdette',
message: 'Étudiant en AE (2020) et Président de lAmicale au moment de la création et du lancement du projet. Lapplication, cétait son idée. Il a beaucoup aidé pour trouver des bugs, de nouvelles fonctionnalités et faire de la com.',
icon: 'account-circle',
btnTrool: null,
btnLinkedin: null,
btnMail: null,
},
theo: {
name: 'Théo Tami',
message: 'Étudiant en IR (2020). Il a beaucoup aidé pour trouver des bugs et proposer des nouvelles fonctionnalités.',
icon: 'account-circle',
btnTrool: null,
btnLinkedin: null,
btnMail: null,
},
};
/**
* Data to be displayed in the app card
*/
@ -115,60 +221,70 @@ class AboutScreen extends React.Component<PropsType> {
];
/**
* Data to be displayed in the author card
* Data to be displayed in the additional developer card
*/
authorData = [
teamData = [
{
onPressCallback: () => {
openWebLink(links.meme);
this.onListItemPress(this.teamUsers.arnaud);
},
icon: 'account-circle',
text: 'Arnaud VERGNET',
icon: this.teamUsers.arnaud.icon,
text: this.teamUsers.arnaud.name,
showChevron: false,
},
{
onPressCallback: () => {
openWebLink(links.authorMail);
this.onListItemPress(this.teamUsers.yohan);
},
icon: 'email',
text: i18n.t('screens.about.authorMail'),
showChevron: true,
},
{
onPressCallback: () => {
openWebLink(links.authorLinkedin);
},
icon: 'linkedin',
text: 'Linkedin',
showChevron: true,
icon: this.teamUsers.yohan.icon,
text: this.teamUsers.yohan.name,
showChevron: false,
},
];
/**
* Data to be displayed in the additional developer card
* Data to be displayed in the thanks card
*/
additionalDevData = [
thanksData = [
{
onPressCallback: () => {},
icon: 'account',
text: 'Yohan SIMARD',
onPressCallback: () => {
this.onListItemPress(this.thanksUsers.beranger);
},
icon: this.thanksUsers.beranger.icon,
text: this.thanksUsers.beranger.name,
showChevron: false,
},
{
onPressCallback: () => {
openWebLink(links.yohanMail);
this.onListItemPress(this.thanksUsers.celine);
},
icon: 'email',
text: i18n.t('screens.about.authorMail'),
showChevron: true,
icon: this.thanksUsers.celine.icon,
text: this.thanksUsers.celine.name,
showChevron: false,
},
{
onPressCallback: () => {
openWebLink(links.yohanLinkedin);
this.onListItemPress(this.thanksUsers.damien);
},
icon: 'linkedin',
text: 'Linkedin',
showChevron: true,
icon: this.thanksUsers.damien.icon,
text: this.thanksUsers.damien.name,
showChevron: false,
},
{
onPressCallback: () => {
this.onListItemPress(this.thanksUsers.titouan);
},
icon: this.thanksUsers.titouan.icon,
text: this.thanksUsers.titouan.name,
showChevron: false,
},
{
onPressCallback: () => {
this.onListItemPress(this.thanksUsers.theo);
},
icon: this.thanksUsers.theo.icon,
text: this.thanksUsers.theo.name,
showChevron: false,
},
];
@ -205,11 +321,59 @@ class AboutScreen extends React.Component<PropsType> {
{
id: 'team',
},
{
id: 'thanks',
},
{
id: 'techno',
},
];
constructor(props: PropsType) {
super(props);
this.state = {
dialogVisible: false,
dialogTitle: '',
dialogMessage: '',
dialogButtons: [],
onDialogDismiss: () => {
this.setState({dialogVisible: false});
},
};
}
/**
* Callback used when clicking an article in the list.
* It opens the modal to show detailed information about the article
*
* @param user TODO
*/
onListItemPress(user: AthorsItemType) {
const dialogBtn: Array<OptionsDialogButtonType> = [
{
title: 'OK',
onPress: () => {
this.onDialogDismiss();
},
}
];
if(user.btnMail != null) {
dialogBtn.push(user.btnMail);
}
if(user.btnLinkedin != null) {
dialogBtn.push(user.btnLinkedin);
}
if(user.btnTrool != null) {
dialogBtn.push(user.btnTrool);
}
this.setState({
dialogVisible: true,
dialogTitle: user.name,
dialogMessage: user.message,
dialogButtons: dialogBtn,
});
}
/**
* Gets the app card showing information and links about the app.
*
@ -255,18 +419,9 @@ class AboutScreen extends React.Component<PropsType> {
)}
/>
<Card.Content>
<Title>{i18n.t('screens.about.author')}</Title>
<FlatList
data={this.authorData}
data={this.teamData}
keyExtractor={this.keyExtractor}
listKey="1"
renderItem={this.getCardItem}
/>
<Title>{i18n.t('screens.about.additionalDev')}</Title>
<FlatList
data={this.additionalDevData}
keyExtractor={this.keyExtractor}
listKey="2"
renderItem={this.getCardItem}
/>
</Card.Content>
@ -274,6 +429,31 @@ class AboutScreen extends React.Component<PropsType> {
);
}
/**
* Gets the thanks card showing information and links about the team TODO
*
* @return {*}
*/
getThanksCard(): React.Node {
return (
<Card style={{marginBottom: 10}}>
<Card.Title
title={i18n.t('screens.about.thanks')}
left={(iconProps: CardTitleIconPropsType): React.Node => (
<Avatar.Icon size={iconProps.size} icon="hand-heart" />
)}
/>
<Card.Content>
<FlatList
data={this.thanksData}
keyExtractor={this.keyExtractor}
renderItem={this.getCardItem}
/>
</Card.Content>
</Card>
);
}
/**
* Gets the techno card showing information and links about the technologies used in the app
*
@ -281,16 +461,21 @@ class AboutScreen extends React.Component<PropsType> {
*/
getTechnoCard(): React.Node {
return (
<Card style={{marginBottom: 10}}>
<Card.Content>
<Title>{i18n.t('screens.about.technologies')}</Title>
<FlatList
data={this.technoData}
keyExtractor={this.keyExtractor}
renderItem={this.getCardItem}
<Card style={{marginBottom: 10}}>
<Card.Title
title={i18n.t('screens.about.technologies')}
left={(iconProps: CardTitleIconPropsType): React.Node => (
<Avatar.Icon size={iconProps.size} icon="build" />
)}
/>
</Card.Content>
</Card>
<Card.Content>
<FlatList
data={this.technoData}
keyExtractor={this.keyExtractor}
renderItem={this.getCardItem}
/>
</Card.Content>
</Card>
);
}
@ -358,6 +543,8 @@ class AboutScreen extends React.Component<PropsType> {
return this.getAppCard();
case 'team':
return this.getTeamCard();
case 'thanks':
return this.getThanksCard();
case 'techno':
return this.getTechnoCard();
default:
@ -374,12 +561,25 @@ class AboutScreen extends React.Component<PropsType> {
keyExtractor = (item: ListItemType): string => item.icon;
render(): React.Node {
const {state} = this;
return (
<CollapsibleFlatList
style={{padding: 5}}
data={this.dataOrder}
renderItem={this.getMainCard}
/>
<View
style={{
height: '100%',
}}>
<CollapsibleFlatList
style={{padding: 5}}
data={this.dataOrder}
renderItem={this.getMainCard}
/>
<OptionsDialog
visible={state.dialogVisible}
title={state.dialogTitle}
message={state.dialogMessage}
buttons={state.dialogButtons}
onDismiss={state.onDialogDismiss}
/>
</View>
);
}
}

Parādīt failu

@ -28,6 +28,7 @@ import MascotPopup from '../../components/Mascot/MascotPopup';
import DashboardManager from '../../managers/DashboardManager';
import type {ServiceItemType} from '../../managers/ServicesManager';
import {getDisplayEvent, getFutureEvents} from '../../utils/Home';
import type {PlanningEventType} from '../../utils/Planning';
// import DATA from "../dashboard_data.json";
const DATA_URL =
@ -49,24 +50,12 @@ export type FeedItemType = {
page_id: string,
};
export type EventType = {
id: number,
title: string,
logo: string | null,
date_begin: string,
date_end: string,
description: string,
club: string,
category_id: number,
url: string,
};
export type FullDashboardType = {
today_menu: Array<{[key: string]: {...}}>,
proximo_articles: number,
available_dryers: number,
available_washers: number,
today_events: Array<EventType>,
today_events: Array<PlanningEventType>,
available_tutorials: number,
};
@ -193,7 +182,7 @@ class HomeScreen extends React.Component<PropsType, StateType> {
* @param content
* @return {*}
*/
getDashboardEvent(content: Array<EventType>): React.Node {
getDashboardEvent(content: Array<PlanningEventType>): React.Node {
const futureEvents = getFutureEvents(content);
const displayEvent = getDisplayEvent(futureEvents);
// const clickPreviewAction = () =>

Parādīt failu

@ -3,110 +3,130 @@
import * as React from 'react';
import {Avatar, Button, Card, Paragraph, withTheme} from 'react-native-paper';
import i18n from 'i18n-js';
import {Linking} from 'react-native';
import type {CustomThemeType} from '../../managers/ThemeManager';
import {Linking, View} from 'react-native';
import CollapsibleScrollView from '../../components/Collapsible/CollapsibleScrollView';
import type {CardTitleIconPropsType} from '../../constants/PaperStyles';
type PropsType = {
theme: CustomThemeType,
};
const links = {
bugsMail: `mailto:app@amicale-insat.fr?subject=[BUG] Application CAMPUS
&body=Coucou Arnaud ça bug c'est nul,\n\n
Informations sur ton système si tu sais (iOS ou Android, modèle du tel, version):\n\n\n
Nature du problème :\n\n\n
Étapes pour reproduire ce pb :\n\n\n\n
Stp corrige le pb, bien cordialement.`,
bugsGit:
'https://git.etud.insa-toulouse.fr/vergnet/application-amicale/issues/new',
bugsGit: 'https://git.etud.insa-toulouse.fr/vergnet/application-amicale/',
trello: 'https://trello.com/b/RMej49Uq/application-campus-insa',
facebook: 'https://www.facebook.com/campus.insat',
feedbackMail: `mailto:app@amicale-insat.fr?subject=[FEEDBACK] Application CAMPUS
&body=Coucou Arnaud j'ai du feedback\n\n\n\nBien cordialement.`,
feedbackDiscord: 'https://discord.gg/W8MeTec',
};
class FeedbackScreen extends React.Component<PropsType> {
class FeedbackScreen extends React.Component<null> {
/**
* Gets link buttons
*
* @param isBug True if buttons should redirect to bug report methods
* @returns {*}
*/
static getButtons(isBug: boolean): React.Node {
static getButtons(isFeedback: boolean): React.Node {
return (
<Card.Actions
style={{
flex: 1,
flexWrap: 'wrap',
}}>
<Button
icon="email"
mode="contained"
style={{
marginLeft: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(isBug ? links.bugsMail : links.feedbackMail);
}}>
MAIL
</Button>
<Button
icon={isBug ? 'git' : 'discord'}
mode="contained"
color={isBug ? '#609927' : '#7289da'}
style={{
marginLeft: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(isBug ? links.bugsGit : links.feedbackDiscord);
}}>
{isBug ? 'GITEA' : 'Discord'}
</Button>
<Button
icon="facebook"
mode="contained"
color="#2e88fe"
style={{
marginLeft: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.facebook);
}}>
Facebook
</Button>
{isFeedback ? (
<View
style={{
flex: 1,
flexWrap: 'wrap',
flexDirection: 'row',
width: '100%',
}}>
<Button
icon="email"
mode="contained"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.feedbackMail);
}}>
MAIL
</Button>
<Button
icon="facebook"
mode="contained"
color="#2e88fe"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.facebook);
}}>
Facebook
</Button>
<Button
icon="discord"
mode="contained"
color="#7289da"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.feedbackDiscord);
}}>
Discord
</Button>
</View>
) : (
<View
style={{
flex: 1,
flexWrap: 'wrap',
flexDirection: 'row',
width: '100%',
}}>
<Button
icon="git"
mode="contained"
color="#609927"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.bugsGit);
}}>
GITETUD
</Button>
<Button
icon="calendar"
mode="contained"
color="#026AA7"
style={{
marginLeft: 'auto',
marginRight: 'auto',
marginTop: 5,
}}
onPress={() => {
Linking.openURL(links.trello);
}}>
TRELLO
</Button>
</View>
)}
</Card.Actions>
);
}
render(): React.Node {
const {theme} = this.props;
return (
<CollapsibleScrollView style={{padding: 5}}>
<Card>
<Card.Title
title={i18n.t('screens.feedback.bugs')}
subtitle={i18n.t('screens.feedback.bugsSubtitle')}
left={(iconProps: CardTitleIconPropsType): React.Node => (
<Avatar.Icon size={iconProps.size} icon="bug" />
)}
/>
<Card.Content>
<Paragraph>{i18n.t('screens.feedback.bugsDescription')}</Paragraph>
<Paragraph style={{color: theme.colors.primary}}>
{i18n.t('screens.feedback.contactMeans')}
</Paragraph>
</Card.Content>
{FeedbackScreen.getButtons(true)}
</Card>
<Card style={{marginTop: 20, marginBottom: 10}}>
<Card.Title
title={i18n.t('screens.feedback.title')}
title={i18n.t('screens.feedback.feedback')}
subtitle={i18n.t('screens.feedback.feedbackSubtitle')}
left={(iconProps: CardTitleIconPropsType): React.Node => (
<Avatar.Icon size={iconProps.size} icon="comment" />
@ -117,6 +137,19 @@ class FeedbackScreen extends React.Component<PropsType> {
{i18n.t('screens.feedback.feedbackDescription')}
</Paragraph>
</Card.Content>
{FeedbackScreen.getButtons(true)}
<Card.Title
title={i18n.t('screens.feedback.contribute')}
subtitle={i18n.t('screens.feedback.contributeSubtitle')}
left={(iconProps: CardTitleIconPropsType): React.Node => (
<Avatar.Icon size={iconProps.size} icon="handshake" />
)}
/>
<Card.Content>
<Paragraph>
{i18n.t('screens.feedback.contributeDescription')}
</Paragraph>
</Card.Content>
{FeedbackScreen.getButtons(false)}
</Card>
</CollapsibleScrollView>

Parādīt failu

@ -5,7 +5,7 @@ import {View} from 'react-native';
import {Card} from 'react-native-paper';
import i18n from 'i18n-js';
import {StackNavigationProp} from '@react-navigation/stack';
import {getDateOnlyString, getFormattedEventTime} from '../../utils/Planning';
import {getDateOnlyString, getTimeOnlyString} from '../../utils/Planning';
import DateManager from '../../managers/DateManager';
import BasicLoadingScreen from '../../components/Screens/BasicLoadingScreen';
import {apiRequest, ERROR_TYPE} from '../../utils/WebData';
@ -96,12 +96,9 @@ class PlanningDisplayScreen extends React.Component<PropsType, StateType> {
const {navigation} = this.props;
const {displayData} = this;
if (displayData == null) return null;
let subtitle = getFormattedEventTime(
displayData.date_begin,
displayData.date_end,
);
let subtitle = getTimeOnlyString(displayData.date_begin);
const dateString = getDateOnlyString(displayData.date_begin);
if (dateString !== null)
if (dateString !== null && subtitle != null)
subtitle += ` | ${DateManager.getInstance().getTranslatedDate(
dateString,
)}`;

Parādīt failu

@ -12,7 +12,7 @@ import {
generateEventAgenda,
getCurrentDateString,
getDateOnlyString,
getFormattedEventTime,
getTimeOnlyString,
} from '../../utils/Planning';
import CustomAgenda from '../../components/Overrides/CustomAgenda';
import {MASCOT_STYLE} from '../../components/Mascot/Mascot';
@ -198,7 +198,7 @@ class PlanningScreen extends React.Component<PropsType, StateType> {
<Divider />
<List.Item
title={item.title}
description={getFormattedEventTime(item.date_begin, item.date_end)}
description={getTimeOnlyString(item.date_begin)}
left={(): React.Node => (
<Avatar.Image
source={{uri: item.logo}}
@ -215,7 +215,7 @@ class PlanningScreen extends React.Component<PropsType, StateType> {
<Divider />
<List.Item
title={item.title}
description={getFormattedEventTime(item.date_begin, item.date_end)}
description={getTimeOnlyString(item.date_begin)}
onPress={onPress}
/>
</View>

Parādīt failu

@ -1,7 +1,7 @@
// @flow
import {stringToDate} from './Planning';
import type {EventType} from '../screens/Home/HomeScreen';
import type {PlanningEventType} from './Planning';
/**
* Gets the time limit depending on the current day:
@ -20,20 +20,6 @@ export function getTodayEventTimeLimit(): Date {
return now;
}
/**
* Gets the duration (in milliseconds) of an event
*
* @param event {EventType}
* @return {number} The number of milliseconds
*/
export function getEventDuration(event: EventType): number {
const start = stringToDate(event.date_begin);
const end = stringToDate(event.date_end);
let duration = 0;
if (start != null && end != null) duration = end - start;
return duration;
}
/**
* Gets events starting after the limit
*
@ -42,11 +28,11 @@ export function getEventDuration(event: EventType): number {
* @return {Array<Object>}
*/
export function getEventsAfterLimit(
events: Array<EventType>,
events: Array<PlanningEventType>,
limit: Date,
): Array<EventType> {
): Array<PlanningEventType> {
const validEvents = [];
events.forEach((event: EventType) => {
events.forEach((event: PlanningEventType) => {
const startDate = stringToDate(event.date_begin);
if (startDate != null && startDate >= limit) {
validEvents.push(event);
@ -55,44 +41,19 @@ export function getEventsAfterLimit(
return validEvents;
}
/**
* Gets the event with the longest duration in the given array.
* If all events have the same duration, return the first in the array.
*
* @param events
*/
export function getLongestEvent(events: Array<EventType>): EventType {
let longestEvent = events[0];
let longestTime = 0;
events.forEach((event: EventType) => {
const time = getEventDuration(event);
if (time > longestTime) {
longestTime = time;
longestEvent = event;
}
});
return longestEvent;
}
/**
* Gets events that have not yet ended/started
*
* @param events
*/
export function getFutureEvents(events: Array<EventType>): Array<EventType> {
export function getFutureEvents(
events: Array<PlanningEventType>,
): Array<PlanningEventType> {
const validEvents = [];
const now = new Date();
events.forEach((event: EventType) => {
events.forEach((event: PlanningEventType) => {
const startDate = stringToDate(event.date_begin);
const endDate = stringToDate(event.date_end);
if (startDate != null) {
if (startDate > now) validEvents.push(event);
else if (endDate != null) {
if (endDate > now || endDate < startDate)
// Display event if it ends the following day
validEvents.push(event);
}
}
if (startDate != null && startDate > now) validEvents.push(event);
});
return validEvents;
}
@ -101,23 +62,19 @@ export function getFutureEvents(events: Array<EventType>): Array<EventType> {
* Gets the event to display in the preview
*
* @param events
* @return {EventType | null}
* @return {PlanningEventType | null}
*/
export function getDisplayEvent(events: Array<EventType>): EventType | null {
export function getDisplayEvent(
events: Array<PlanningEventType>,
): PlanningEventType | null {
let displayEvent = null;
if (events.length > 1) {
const eventsAfterLimit = getEventsAfterLimit(
events,
getTodayEventTimeLimit(),
);
if (eventsAfterLimit.length > 0) {
if (eventsAfterLimit.length === 1) [displayEvent] = eventsAfterLimit;
else displayEvent = getLongestEvent(events);
} else {
displayEvent = getLongestEvent(events);
}
} else if (events.length === 1) {
[displayEvent] = events;
}
if (eventsAfterLimit.length > 0) [displayEvent] = eventsAfterLimit;
else [displayEvent] = events;
} else if (events.length === 1) [displayEvent] = events;
return displayEvent;
}

Parādīt failu

@ -3,13 +3,13 @@
export type PlanningEventType = {
id: number,
title: string,
logo: string,
date_begin: string,
date_end: string,
description: string,
club: string,
category_id: number,
description: string,
place: string,
url: string,
logo: string | null,
};
// Regex used to check date string validity
@ -120,50 +120,6 @@ export function getTimeOnlyString(dateString: string): string | null {
return null;
}
/**
* Returns a string corresponding to the event start and end times in the following format:
*
* HH:MM - HH:MM
*
* If the end date is not specified or is equal to start time, only start time will be shown.
*
* If the end date is not on the same day, 23:59 will be shown as end time
*
* @param start Start time in YYYY-MM-DD HH:MM:SS format
* @param end End time in YYYY-MM-DD HH:MM:SS format
* @return {string} Formatted string or "/ - /" on error
*/
export function getFormattedEventTime(start: string, end: string): string {
let formattedStr = '/ - /';
const startDate = stringToDate(start);
const endDate = stringToDate(end);
if (
startDate !== null &&
endDate !== null &&
startDate.getTime() !== endDate.getTime()
) {
formattedStr = `${String(startDate.getHours()).padStart(2, '0')}:${String(
startDate.getMinutes(),
).padStart(2, '0')} - `;
if (
endDate.getFullYear() > startDate.getFullYear() ||
endDate.getMonth() > startDate.getMonth() ||
endDate.getDate() > startDate.getDate()
)
formattedStr += '23:59';
else
formattedStr += `${String(endDate.getHours()).padStart(2, '0')}:${String(
endDate.getMinutes(),
).padStart(2, '0')}`;
} else if (startDate !== null)
formattedStr = `${String(startDate.getHours()).padStart(2, '0')}:${String(
startDate.getMinutes(),
).padStart(2, '0')}`;
return formattedStr;
}
/**
* Checks if the given description can be considered empty.
* <br>