272 Commits

Author SHA1 Message Date
6c2324cb91 fix set settings 2025-09-07 20:51:27 +02:00
5ee053272e Merge pull request 'hotfix/fix-upgrade' (#50) from hotfix/fix-upgrade into main
Reviewed-on: #50
2025-09-05 21:32:28 +00:00
1bb2612de3 add initialOrga as vide 2025-09-05 23:09:20 +02:00
86f81ff009 add marker red 2025-09-04 18:11:12 +02:00
9989aebc32 add zoom after click 2025-09-04 17:26:00 +02:00
35fc1cfa25 add zoomfit 2025-09-04 09:04:24 +02:00
692d55858c add selectecmode 2025-09-02 23:18:46 +02:00
59b16e5131 fix lat lng 2025-09-02 23:05:49 +02:00
89c5e1aa6c fix set mapbox token 2025-09-02 16:32:50 +02:00
f4fb846855 fix login 2025-09-02 14:25:19 +02:00
9a9287bd20 fix permissions 2025-09-02 13:58:39 +02:00
210da71d50 fix notification local 2025-09-02 10:15:03 +02:00
63ea3091e8 fix flutter_notifications_lcoal 2025-09-01 23:07:40 +02:00
3310bd572e fix mapbox pages 2025-09-01 22:14:08 +02:00
6d504139b0 fix gemini prompt 2025-08-31 21:08:58 +02:00
6169483839 fix new version applocalization 2025-08-31 18:24:49 +02:00
2f74f5ed78 fix applocalizations 2025-08-31 18:22:40 +02:00
b6134c5506 upgrade mapbox 2025-08-29 23:24:27 +02:00
70545052c2 Merge pull request 'feature/notification-date' (#49) from feature/notification-date into main
Reviewed-on: #49
2025-08-27 21:53:17 +00:00
6e0b54a925 remove debug 2025-08-27 23:51:08 +02:00
5d9802d56e ask permission 2025-08-26 20:57:50 +02:00
8a7515aaf6 add list in listitem 2025-08-26 20:34:01 +02:00
f9934a0d5d debug ok 2025-08-26 20:29:55 +02:00
09c82da57f add notification test 2025-08-25 23:41:54 +02:00
75b42dd091 Merge pull request 'feature/event-interested' (#48) from feature/event-interested into main
Reviewed-on: #48
2025-08-20 21:40:43 +00:00
dfe21960be add toggle interested in list organizer and tag 2025-08-20 23:39:20 +02:00
4a936cc267 change for heart and and count interested people 2025-08-20 23:22:25 +02:00
bd5bfa94ca remove print debug 2025-08-20 22:49:51 +02:00
f30aa8f630 togleInterested debug 2025-08-19 21:09:44 +02:00
924794e8a0 ad toogle interested method 2025-08-19 00:11:40 +02:00
7528e55dca add button star 2025-08-17 17:42:02 +02:00
02ba067615 Merge pull request 'feature/link' (#47) from feature/link into main
Reviewed-on: #47
2025-08-15 21:19:14 +00:00
9eafb30374 add link and ticket backend side 2025-08-15 23:05:53 +02:00
24cb90959d fix edit event 2025-08-15 17:14:53 +02:00
1620d84137 add link and ticket inàut 2025-08-15 00:29:48 +02:00
6e8ba642a2 add link and ticket 2025-08-12 23:33:15 +02:00
0113fcc382 add Link 2025-08-12 22:30:12 +02:00
e4571cabe7 Merge pull request 'feature/internationale' (#46) from feature/internationale into main
Reviewed-on: #46
2025-08-06 20:38:36 +00:00
76db2f8254 add cache for language 2025-08-06 22:34:01 +02:00
0a62011b3a translate date on list by tag and by organizer 2025-08-06 22:17:53 +02:00
cbc75bbc7b translate date 2025-07-30 23:54:15 +02:00
7a418d82a7 Add german translation 2025-07-29 21:21:21 +02:00
e310197aa7 translate updateevent 100% 2025-07-28 23:21:37 +02:00
5d02f2b1fb translate updateevent 50% 2025-07-28 22:56:39 +02:00
119dfcbdfe translate mapbox page 100% 2025-07-27 20:51:55 +02:00
9e50b6d6f6 translate mapbox page 50% 2025-07-27 20:43:35 +02:00
dcc2ec25de translate mapbox page 10% 2025-07-27 20:04:55 +02:00
2c2eedb7ce translate loginpage 100% 2025-07-27 15:16:38 +02:00
089aa58f4a ListItemOrganizer and Tags 2025-07-27 12:13:52 +02:00
b4b0199fc2 ItemMenu 100% 2025-07-26 19:23:59 +02:00
b48483c9f0 translate forgotpassword 100% again 2025-07-26 19:00:28 +02:00
22d0581da3 translate forgotpassword 100% 2025-07-25 23:44:58 +02:00
337fab4a08 translate editsettings 100% 2025-07-25 23:20:51 +02:00
a99986813e translate editprofile 100% 2025-07-25 23:04:28 +02:00
199000035e translate editprofile 75% 2025-07-24 21:04:27 +02:00
f143036ca8 translate editevent 100% 2025-07-24 20:42:25 +02:00
271c3ba118 translate editevent 75% 2025-07-24 20:25:52 +02:00
f8b5c24efd translate editevent 55% 2025-07-23 23:28:16 +02:00
1df36987d9 translate editevent 50% 2025-07-23 23:18:52 +02:00
b4dc29aff6 translate displaypicturescreen 100% 2025-07-21 22:50:56 +02:00
79563e829c Add displaypicture 2025-07-18 19:38:10 +02:00
413807f039 Add camera dart 2025-07-18 19:06:38 +02:00
26372368b2 full translate for AddProfile pages 100% 2025-07-17 20:53:07 +02:00
f81a8c264c full translate for AddProfile pages 28% 2025-07-16 23:32:35 +02:00
c5985f2954 full translate for AddProfile pages 26% 2025-07-16 23:05:49 +02:00
1f8d18343c full translate for AddProfile pages 25% 2025-07-16 22:58:01 +02:00
c3b8b0df14 full translate for AddProfile pages 20% 2025-07-16 22:46:41 +02:00
ec8ce404ab full translate for AddProfile pages 16% 2025-07-16 22:08:08 +02:00
1208982b15 full translate for AddProfile pages 15% 2025-07-14 23:20:22 +02:00
479ab76fb7 full translate for AddProfile pages 10% 2025-07-14 22:53:34 +02:00
1646a0b6e3 full translate for ItemListMenu pages 50% 2025-07-09 23:33:04 +02:00
e21b03d13c full translate for ItemListMenu pages 2025-07-09 23:05:50 +02:00
45cdb253e4 internationlization wip 2025-07-06 20:59:57 +02:00
75b443758a changement de langue ok sur drawer 2025-07-02 22:35:53 +02:00
e2195e6500 change language ok 2025-07-02 22:03:51 +02:00
4f41aff572 change button language 2025-06-30 23:25:56 +02:00
1c21f59420 Merge pull request 'feature/localeDate' (#45) from feature/localeDate into main
Reviewed-on: #45
2025-06-25 19:16:50 +00:00
7441af6f13 remove if body isnotempty 2025-06-25 21:14:45 +02:00
4f4b0b609c add date locale in list by tags 2025-06-23 23:25:34 +02:00
2e6814c33d add date locale in list by organizers 2025-06-23 23:17:05 +02:00
909b321158 test date format french ok for first page 2025-06-23 23:09:37 +02:00
6641c7938c Merge pull request 'add fetchcount' (#44) from hotfix/fix-counter into main
Reviewed-on: #44
2025-06-23 20:02:46 +00:00
8904032265 add fetchcount 2025-06-18 23:36:24 +02:00
9d35a59ba6 Merge pull request 'hotfix/duplicate-event' (#43) from hotfix/duplicate-event into main
Reviewed-on: #43
2025-06-16 21:05:14 +00:00
303447ff1e check duplicate event 2025-06-16 22:51:01 +02:00
32532246eb add duplicate event check 2025-06-11 23:05:00 +02:00
452faf05d8 Merge pull request 'feature/pagination' (#42) from feature/pagination into main
Reviewed-on: #42
2025-06-02 21:22:13 +00:00
3a64f1ae36 add pagination for other pages 2025-06-02 23:03:49 +02:00
afae3293c4 add current date 2025-06-02 22:22:33 +02:00
600bf8d2f4 add pagination with limit 2025-05-30 23:39:50 +02:00
ec7a286074 pagination wip 2025-05-27 23:36:19 +02:00
6c1c650fa1 add last data 2025-05-25 23:39:37 +02:00
7468c5f24c change fetchCOunt 2025-05-23 23:47:17 +02:00
1bcc8372c6 pagination work for main page 2025-05-23 00:01:48 +02:00
510e366216 add pagination 2025-03-24 22:47:49 +01:00
52580c6568 fetchCount to 0 2025-03-24 22:10:49 +01:00
4f7c8f60d0 add increment and decrement to pagination 2025-03-19 23:40:38 +01:00
ce2a061bf0 Merge pull request 'persist encrypt shared' (#41) from feature/add-encrypted-sharepreferences into main
Reviewed-on: #41
2025-03-12 21:58:27 +00:00
04f4b7ce8e persist encrypt shared 2025-03-12 22:48:35 +01:00
78ea5f0c10 Merge pull request 'add remember me' (#40) from feature/persist-connect into main
Reviewed-on: #40
2025-03-06 22:38:26 +00:00
395d3390cf add remember me 2025-03-06 23:37:29 +01:00
daef20db66 Merge pull request 'feature/check-token' (#39) from feature/check-token into main
Reviewed-on: #39
2025-03-06 20:39:44 +00:00
9df499d198 check token 100% 2025-03-06 21:38:47 +01:00
e7afe8fddb add check token 25% 2025-03-06 21:27:06 +01:00
5c2a58e484 remove package fix 2025-03-06 20:38:15 +01:00
e8bb2f6180 Merge pull request 'feature/oauth' (#38) from feature/oauth into main
Reviewed-on: #38
2025-03-06 19:27:01 +00:00
e4d8648fcc remove pakcage 2025-03-06 20:26:02 +01:00
7f3240242d remove google and facebook auth 2025-03-06 20:21:59 +01:00
c936a02836 re-organisation login info 2025-03-02 16:49:19 +01:00
3352bab860 Merge pull request 'feature/publicite' (#37) from feature/publicite into main
Reviewed-on: #37
2025-02-23 21:20:24 +00:00
c31e275dae add pub 2025-02-23 22:18:01 +01:00
38e9908533 add pub 2025-02-19 23:32:31 +01:00
47c014cdda add pub in update event 2025-02-19 23:24:21 +01:00
729e0ce1ca use many pub in different page 2025-02-19 23:03:12 +01:00
5c2fa27aa7 ad helper 2025-02-18 22:56:50 +01:00
9846c614a1 Merge pull request 'feature/forgotPassword' (#36) from feature/forgotPassword into main
Reviewed-on: #36
2025-02-15 11:26:45 +00:00
d46f268c1b mise en forme 2025-02-15 12:25:03 +01:00
b0477c889c add page password forgot 2025-02-14 23:39:44 +01:00
6fdb5cb2fe Merge pull request 'feature/add-user' (#35) from feature/add-user into main
Reviewed-on: #35
2025-02-14 20:21:05 +00:00
c1352b8eeb add profil ok 2025-02-14 21:19:44 +01:00
90e61cebbf add profile wip 2025-01-22 23:33:09 +01:00
6a3ec9a969 remove useless function 2025-01-22 23:12:47 +01:00
11c8cd74d2 add profile 2025-01-22 23:03:06 +01:00
39c60632f1 Merge pull request 'add getDouble' (#34) from feature/parameter-kilometer into main
Reviewed-on: #34
2025-01-22 21:02:45 +00:00
c5a280d91b add getDouble 2025-01-22 21:49:16 +01:00
280909deb9 Merge pull request 'feature/refactor' (#33) from feature/refactor into main
Reviewed-on: #33
2025-01-21 06:57:24 +00:00
b7fe1da681 refactor code 2025-01-20 21:42:14 +01:00
56ae77137c refactor listitemmenu 2025-01-19 22:41:13 +01:00
06e26240ab refactor itemmenu 2025-01-19 22:26:45 +01:00
908d94c269 fix import 2025-01-19 21:49:09 +01:00
642f35e73c Merge pull request 'feature/hamburger-bar' (#32) from feature/hamburger-bar into main
Reviewed-on: #32
2025-01-10 22:20:41 +01:00
524427a29f add drawer to every page 2025-01-10 21:06:41 +01:00
54c95a230b set kilometer in double 2025-01-09 23:27:22 +01:00
18d5c83181 add kilometer 2025-01-09 22:13:20 +01:00
b156cd084b remove useless input editSettings 2025-01-09 21:48:24 +01:00
3bb85a198a add edit settings 2025-01-09 21:44:43 +01:00
0f40c3e225 add home link 2025-01-09 21:35:31 +01:00
30b9be35ef edit profile ok 2025-01-06 23:40:17 +01:00
db3cb20255 add check condition isnotempty 2025-01-05 21:02:39 +01:00
83c65be610 informations filled 2025-01-05 17:53:14 +01:00
da3659e84a add edit profile 2025-01-05 17:38:31 +01:00
39b3efca33 redirect to page update profile 2025-01-04 14:25:34 +01:00
82c31acf99 editprofile complete 2025-01-03 19:15:35 +01:00
f84f513e67 update function update 2025-01-03 18:03:24 +01:00
3615c1f476 fix edit profile wip 2025-01-03 17:22:14 +01:00
5419da7a98 edit profile wip 2025-01-03 15:06:08 +01:00
ef8b8c96c0 edit profile wip 2025-01-02 23:22:25 +01:00
ad19ea54d1 add account update 2024-12-30 23:48:03 +01:00
ef87a8bfe2 add logout button + logout function 2024-12-30 23:33:51 +01:00
8adcd80306 message about 2024-12-30 22:51:47 +01:00
43d77f778b change alert message 2024-12-30 22:34:17 +01:00
938b677b6e test hamburger bar 2024-12-30 22:14:46 +01:00
6e5994e4dd Merge pull request 'change suggestions list for input geo' (#31) from hotfix/refactor-input-tags into main
Reviewed-on: #31
2024-12-30 21:55:30 +01:00
b2e7080265 change suggestions list for input geo 2024-12-28 15:03:55 +01:00
d8b3bf7ca2 Merge pull request 'feature/suggestion-tag' (#30) from feature/suggestion-tag into main
Reviewed-on: #30
2024-12-28 14:52:39 +01:00
0df538ef46 recherche par tags terminé 2024-12-28 14:47:39 +01:00
48c785c586 change mapbox place to google place api 2024-12-27 23:31:49 +01:00
c5de20d64b change place api mapbox to google place api 2024-12-25 22:18:02 +01:00
43124d9cb9 add list adress from v6 mapbox and searchbox 2024-12-22 22:37:17 +01:00
03f3e1c55b add suggestion itemé 2024-12-22 22:11:20 +01:00
ba8db9fb4c add suggestion for inputtags 2024-12-22 16:00:10 +01:00
53a60a581a fix tags input 2024-12-21 20:19:33 +01:00
e4836ac4eb manage show input 2024-12-21 19:06:37 +01:00
f267e3ede9 add inputtext simple 2024-12-21 14:15:49 +01:00
eadf07177b simple textfield 2024-12-20 22:44:05 +01:00
18fdc7d6c4 add tags 2024-12-16 22:26:58 +01:00
8d8c30f506 Merge pull request 'feature/edit-image' (#29) from feature/edit-image into main
Reviewed-on: #29
2024-12-15 20:23:19 +01:00
ea3d5ef8de add post image in edit eventé 2024-12-15 20:10:19 +01:00
578107c83c add cameraedit 2024-12-14 21:30:32 +01:00
49a108905c add button edit image 2024-12-14 19:10:23 +01:00
32281233e0 Merge pull request 'feature/edit-event' (#28) from feature/edit-event into main
Reviewed-on: #28
2024-12-14 18:44:21 +01:00
63f6bd2af2 edit event without edit image 2024-12-14 00:34:08 +01:00
c58127342b display edit event 2024-12-13 23:49:56 +01:00
0dc098554c tags and organizers work 2024-12-11 22:20:32 +01:00
b8e6adf2e8 try tags organizers 2024-12-09 23:34:44 +01:00
ac566053b1 fix datepicker 2024-12-09 23:00:54 +01:00
c12a957099 fix datetpicker wip 2024-12-08 21:23:51 +01:00
4b71867ee0 add editevent wip 2024-12-07 18:44:53 +01:00
8c4c436241 add floating button 2024-12-07 17:10:02 +01:00
1cc14277e8 Merge pull request 'feature/fix-search' (#27) from feature/fix-search into main
Reviewed-on: #27
2024-12-04 23:29:39 +01:00
cf100651eb check existing event before add 2024-12-04 23:28:09 +01:00
76f1de27ec add future event only 2024-12-04 23:01:06 +01:00
eef7e44999 change endpoint 2024-12-01 21:23:22 +01:00
3315cf1961 Merge pull request 'hide clear button' (#26) from feature/hide-clear-button into main
Reviewed-on: #26
2024-11-30 19:29:24 +01:00
a4b747a273 hide clear button 2024-11-30 19:28:43 +01:00
6b53dc170d Merge pull request 'feature/suggestion-item' (#25) from feature/suggestion-item into main
Reviewed-on: #25
2024-11-30 19:00:07 +01:00
0977389695 suggestion search by item 2024-11-30 18:45:41 +01:00
559b35c7c2 add suggestion for search item 2024-11-30 00:39:57 +01:00
edd2cd1581 add suggesstion item wip 2024-11-28 23:44:11 +01:00
d012ac409b Merge pull request 'fix input geo search' (#24) from hotfix/inputgeo into main
Reviewed-on: #24
2024-11-28 22:32:44 +01:00
4ec4b79f2c fix input geo search 2024-11-28 22:26:12 +01:00
7f4f59b6c9 Merge pull request 'fix suggesstion list' (#23) from hotfix/fix-inputgeo into main
Reviewed-on: #23
2024-11-26 21:46:51 +01:00
0e3d75e8a8 fix suggesstion list 2024-11-26 21:43:14 +01:00
d93c10f319 Merge pull request 'change place input + fix endpoint' (#22) from hotfix/search into main
Reviewed-on: #22
2024-11-24 22:45:24 +01:00
a5533aa0d3 change place input + fix endpoint 2024-11-24 22:44:35 +01:00
4b75abe6b6 Merge pull request 'add pint bar search by item' (#21) from feature/model-input into main
Reviewed-on: #21
2024-11-24 21:44:02 +01:00
8a46958e7c add pint bar search by item 2024-11-24 21:41:01 +01:00
f85894416c Merge pull request 'hide input date' (#20) from feature/hide-input into main
Reviewed-on: #20
2024-11-23 22:32:19 +01:00
dbba3304c2 hide input date 2024-11-23 22:20:27 +01:00
6b3bf5004c Merge pull request 'feature/input-date' (#19) from feature/input-date into main
Reviewed-on: #19
2024-11-23 21:54:00 +01:00
bae64ebd35 add start_date and end_date 2024-11-23 21:52:50 +01:00
431b8d78ad search by date work 2024-11-23 17:59:52 +01:00
d4f8ee2182 add parameter 2024-11-23 17:24:46 +01:00
627eb778ad add cache for latitude and use in searchdelagate 2024-11-23 13:29:25 +01:00
23aec689f1 add condition 2024-11-23 13:14:24 +01:00
a0ece6f973 passing parameter 2024-11-23 10:50:57 +01:00
c6a0c2f4f1 add cache for position 2024-11-23 10:42:32 +01:00
f693ffa6b8 merge commit 2024-11-23 09:56:37 +01:00
93beabe884 Merge branch 'main' into feature/input-date 2024-11-23 09:39:06 +01:00
cdae84090f add input date 2024-11-20 23:48:01 +01:00
a7d8bebe1f Merge pull request 'precision medium - more fast geolocation' (#18) from hotfix/geolocation-slow into main
Reviewed-on: #18
2024-11-20 23:20:51 +01:00
4a313fc725 precision medium - more fast geolocation 2024-11-20 23:19:35 +01:00
4d3533eb8a Merge pull request 'add loading with gestion error' (#17) from feature/loading-image into main
Reviewed-on: #17
2024-11-18 22:16:40 +01:00
1f6d9bbcd0 add loading with gestion error 2024-11-18 21:37:19 +01:00
5e0b541786 Merge pull request 'changer marker red' (#16) from hotfix/change-icon into main
Reviewed-on: #16
2024-11-17 15:55:35 +01:00
b7dc682e2f changer marker red 2024-11-17 15:53:26 +01:00
67b56b5764 Merge pull request 'feature/routing-map' (#15) from feature/routing-map into main
Reviewed-on: #15
2024-11-17 12:56:18 +01:00
de6a7f2399 icons worked 2024-11-17 11:38:59 +01:00
c8223d9b7d remove line after change 2024-11-17 11:31:07 +01:00
7f5d59857c re-zoom ok 2024-11-17 11:10:43 +01:00
af65dc1cb0 geolocation first 2024-11-17 10:58:29 +01:00
4a04520800 add messae error 2024-11-17 10:46:17 +01:00
f880ac1002 add direction 75% 2024-11-16 23:24:00 +01:00
d4842b4d67 Merge pull request 'feature/mapfromadress' (#14) from feature/mapfromadress into main
Reviewed-on: #14
2024-11-16 21:41:57 +01:00
9146fd02e4 add title - subtile in list 2024-11-16 21:35:16 +01:00
79f457eec1 more precise search 2024-11-16 20:06:58 +01:00
74e55f3d6b get lati long from backend 2024-11-15 23:22:17 +01:00
7182e0e324 fix add marker style 2024-11-15 22:48:05 +01:00
be8b0d3b66 add marker 2024-11-13 23:47:40 +01:00
2e1b25264a add mapbox 2024-11-11 14:48:23 +01:00
701f6dbacf Merge pull request 'fix current date' (#13) from feature/getcurrentdate into main
Reviewed-on: #13
2024-11-11 11:53:39 +01:00
8b1db195d7 fix current date 2024-11-11 11:52:21 +01:00
c8bcd254dd Merge pull request 'feature/getcurrentdate' (#12) from feature/getcurrentdate into main
Reviewed-on: #12
2024-11-11 11:51:16 +01:00
76ab0aef48 fix datetime 2024-11-11 11:46:42 +01:00
a427fc5edf current date 2024-11-10 18:18:08 +01:00
c1e85c255e Merge pull request 'feature/searchbar' (#11) from feature/searchbar into main
Reviewed-on: #11
2024-11-08 17:55:12 +01:00
1580d7a3cc ajout d'une date de fin si jamais, c'est vide 2024-11-08 17:07:40 +01:00
00a9125eb2 fix datepicker 2024-11-08 16:57:07 +01:00
44a0691e31 add latitude and longitude 2024-11-07 23:10:03 +01:00
b22458021b get events from current position 2024-11-06 15:55:15 +01:00
5c0f4d345d get location from starting app 2024-11-06 13:27:31 +01:00
3a0f24cc4c search item with geographical search 2024-11-05 23:29:55 +01:00
b796d0206f geographical search bars does works 2024-11-05 15:59:31 +01:00
517652df98 searchbar works but return empty doesn't refresh 2024-11-05 15:11:53 +01:00
951127d7bc add searchbar 2024-11-04 23:53:24 +01:00
3a350e33cc add searchbar with mapbox and suggesstionbar 2024-10-28 23:50:20 +01:00
576d045cd8 add searchbar by geographical zone 2024-10-28 22:52:00 +01:00
4e0222d4bb add second searchbar to search by geographical zone 2024-10-26 17:51:31 +02:00
c43eb789b1 fix icons camera 2024-10-23 23:56:04 +02:00
6c806b1a39 add searchbar 2024-10-23 22:43:03 +02:00
b31e35504f Merge pull request 'feature/category' (#10) from feature/category into main
Reviewed-on: #10
2024-10-21 23:14:08 +02:00
f2de4a2faa overflow text 2024-10-21 22:47:04 +02:00
df80137f46 add organizers item list 2024-10-21 22:29:02 +02:00
3861a3c5e1 list item menu by tags 2024-10-21 22:02:21 +02:00
8b87f55bf9 flexible horizontal tags 2024-10-20 20:27:17 +02:00
519d20fd63 add organizateurs 2024-10-20 18:23:34 +02:00
fb34b41385 direction vertical 2024-10-20 11:46:51 +02:00
f2cd070898 add tags in item 2024-10-20 11:32:33 +02:00
045209575e fix datepicker 2024-10-18 22:53:50 +02:00
792ce0227e add string orga 2024-10-18 21:40:20 +02:00
f0780c2a3e add organizers 2024-10-18 21:28:46 +02:00
b3c4980b52 input organizaters wip 2024-10-15 23:57:22 +02:00
4d73360f74 add tags to api 2024-10-15 23:44:41 +02:00
b1ca67ed72 add tags automatically 2024-10-14 17:49:39 +02:00
b1a8b932b9 tags work 2024-10-09 23:28:24 +02:00
7e6de0aa38 input tags 50% 2024-10-07 23:59:15 +02:00
47d80791e5 add input categories 2024-10-03 23:54:54 +02:00
112eab3125 Merge pull request 'feature/update-desc' (#9) from feature/update-desc into main
Reviewed-on: #9
2024-09-29 14:14:25 +02:00
b283165a86 formatting text 2024-09-29 12:52:02 +02:00
45dc5d6c84 formating text description 2024-09-29 12:35:52 +02:00
47dfcc3632 add flexible 2024-09-29 11:02:27 +02:00
1cdae0bb33 add info for event 2024-09-25 23:08:28 +02:00
342 changed files with 26345 additions and 1881 deletions

View File

@@ -1,15 +0,0 @@
class Events {
String? id;
String? name;
String? place;
String? startDate;
Events({this.place, this.id, this.name, this.startDate});
Events.fromJson(Map<String, dynamic> json) {
id = json['id'];
name = json['name'];
place = json['place'];
startDate = json["start_date"];
}
}

View File

@@ -1,241 +0,0 @@
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
import 'dart:convert';
import 'dart:io';
//import 'MyHomePage.dart';
import 'pages/ListItemMenu.dart';
import 'classes/alert.dart';
import 'variable/globals.dart' as globals;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: LoginDemo(),
);
}
}
class LoginDemo extends StatefulWidget {
@override
_LoginDemoState createState() => _LoginDemoState();
}
class _LoginDemoState extends State<LoginDemo> with ShowErrorDialog {
TextEditingController inputPseudo = TextEditingController();
TextEditingController inputPassword = TextEditingController();
Future<void> _login(BuildContext context) async {
var url = Uri.parse("${globals.api}/token");
var pseudo = inputPseudo.text;
var password = inputPassword.text;
print("get login");
print(pseudo.isNotEmpty);
print(password.isNotEmpty);
if ((pseudo.isNotEmpty) && (password.isNotEmpty)) {
print(url);
try {
//String credentials = "${pseudo}:${password}";
//Codec<String, String> stringToBase64 = utf8.fuse(base64);
//String encoded = stringToBase64.encode(credentials);
var response = await http.post(url,
// headers: {
// HttpHeaders.authorizationHeader: 'Basic $encoded',
//}
headers: {
'accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
},
body: {
"username": "${pseudo}",
"password": "${password}"
});
print(response.statusCode);
if ((response.statusCode == 200) || (response.statusCode == 201)) {
SharedPreferences prefs = await SharedPreferences.getInstance();
var cookies = response.headers["set-cookie"].toString().split(";");
for (var cookie in cookies) {
var cookiesMany = cookie.split(",");
for (var cookie2 in cookiesMany) {
switch (cookie2.split("=")[0]) {
case "access_token":
{
prefs.setString("access_token", cookie2.split("=")[1]);
}
break;
default:
break;
}
}
}
Navigator.push(
context, MaterialPageRoute(builder: (_) => ListItemMenu()));
} else {
var text = "";
switch (response.statusCode) {
case 400:
{
text = "Requête mal construite";
}
break;
case 406:
{
text = "Mot de passe incorrect";
}
break;
case 404:
{
text = "Utilisateur inconnu";
}
break;
case 403:
{
text = "Utilisateur desactive";
}
break;
case 410:
{
text = "Token invalide";
}
break;
case 500:
{
text = "Probleme interne du serveur";
}
break;
default:
{
text = "Probleme d'authentification inconnu";
}
break;
}
showErrorDialog(context, text);
}
} catch (e) {
showErrorDialog(context, "${e}");
}
} else {
showErrorDialog(context, "Champ vide");
}
}
void start() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var access_token = prefs.getString("access_token") ?? "";
print("Get access token");
if (access_token.isNotEmpty) {
print("Appel HTTP");
var urlToken = Uri.parse("${globals.api}/token");
var responseToken = await http.get(urlToken,
headers: {HttpHeaders.cookieHeader: 'access_token: ${access_token}'});
print(responseToken.statusCode);
if (responseToken.statusCode == 200) {
print("route to item list");
Navigator.push(
context, MaterialPageRoute(builder: (_) => ListItemMenu()));
} else {
prefs.remove("access_token");
}
}
}
@override
void initState() {
start();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text("Login Page"),
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Center(
child: Container(
width: 200,
height: 150,
decoration: BoxDecoration(
color: Colors.red,
borderRadius: BorderRadius.circular(50.0)),
child: Image.asset('./images/flutter.png')),
),
),
Padding(
//padding: const EdgeInsets.only(left:15.0,right: 15.0,top:0,bottom: 0),
padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
controller: inputPseudo,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Pseudo',
hintText: 'Enter pseudo existent'),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
controller: inputPassword,
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Password',
hintText: 'Enter secure password'),
),
),
TextButton(
onPressed: () {
//TODO FORGOT PASSWORD SCREEN GOES HERE
},
child: Text(
'Forgot Password',
style: TextStyle(color: Colors.blue, fontSize: 15),
),
),
Container(
height: 50,
width: 250,
decoration: BoxDecoration(
color: Colors.blue, borderRadius: BorderRadius.circular(20)),
child: TextButton(
onPressed: () {
_login(context);
},
child: Text(
'Login',
style: TextStyle(color: Colors.white, fontSize: 25),
),
),
),
SizedBox(
height: 130,
),
Text('New User? Create Account')
],
),
),
);
}
}

View File

@@ -1,164 +0,0 @@
import 'package:flutter/material.dart';
import 'dart:io';
import '../classes/addEventImage.dart';
import '../classes/alert.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_gemini/flutter_gemini.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
import "ItemMenu.dart";
import 'UpdateEventImage.dart';
import 'dart:convert';
import '../variable/globals.dart' as globals;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
);
}
}
// A screen that allows users to take a picture using a given camera.
class DisplayPictureScreen extends StatefulWidget {
final String imagePath;
const DisplayPictureScreen({super.key, required this.imagePath});
@override
DisplayPictureScreenState createState() => DisplayPictureScreenState();
}
// A widget that displays the picture taken by the user.
class DisplayPictureScreenState extends State<DisplayPictureScreen>
with ShowDescImageAdd, ShowErrorDialog, TickerProviderStateMixin {
late AnimationController controller;
@override
void initState() {
controller = AnimationController(
/// [AnimationController]s can be created with `vsync: this` because of
/// [TickerProviderStateMixin].
vsync: this,
duration: const Duration(seconds: 5),
)..addListener(() {
setState(() {});
});
controller.repeat(reverse: false);
super.initState();
_getEventInfosFromImage();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
Future<void> displayError(String e) async {
print("problem gemini : ${e}");
showErrorDialog(context,
"L'IA de Google n'a pas su analyser l'image. Recommecer avec une autre");
}
Future<void> searchEvents(String json, String imagePath) async {
print(json);
SharedPreferences prefs = await SharedPreferences.getInstance();
Map<String, dynamic> jsonData = jsonDecode(json);
var name = jsonData["name"];
var place = jsonData["place"];
var accessToken = prefs.getString("access_token") ?? "";
if (accessToken.isNotEmpty) {
var urlGet = Uri.parse("${globals.api}/events?name=${name}");
var responseGet = await http.get(urlGet,
headers: {HttpHeaders.cookieHeader: 'access_token=${accessToken}'});
if (responseGet.statusCode == 200) {
var events = jsonDecode(utf8.decode(responseGet.bodyBytes));
print("reponse http : ${events.length}");
if (events.length == 0) {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => UpdateeventImage(
events: jsonData, imagePath: imagePath)));
} else {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => ItemMenu(title: events[0]["id"])));
}
}
} else {
showErrorDialog(context, "Erreur de token");
}
//showDescImageAddDialog(context, message);
}
Future<void> _getEventInfosFromImage() async {
await dotenv.load();
final gemini = Gemini.init(
apiKey: dotenv.env['GEMINI_API_KEY']!, enableDebugging: true);
final file = File(widget.imagePath);
gemini
.textAndImage(
text:
"Peux-tu donner le nom, la date avec l'année actuelle ou d'une année future proche et le lieu de l'évènement sous format JSON avec les valeurs suivantes : name, address, city, zip_code, country, description, start_date et end_date sous le format en YYYY-MM-DD HH:mm:ssZ, et sans la présence du mot json dans la chaîne de caractère",
images: [file.readAsBytesSync()],
modelName: "models/gemini-1.5-pro-latest")
.then((value) => searchEvents(
value?.content?.parts?.last.text ?? '', widget.imagePath))
.catchError((e) => displayError);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(title: const Text('Display the Picture')),
// The image is stored as a file on the device. Use the `Image.file`
// constructor with the given path to display the image.
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
Text(
'Analyse de l\'image en cours',
style: Theme.of(context).textTheme.titleLarge,
),
CircularProgressIndicator(
value: controller.value,
semanticsLabel: 'Loading progress',
),
])));
}
}

View File

@@ -1,238 +0,0 @@
// ignore_for_file: unnecessary_brace_in_string_interps
import 'dart:io';
import 'dart:convert';
import 'package:covas_mobile/classes/alert.dart';
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:shared_preferences/shared_preferences.dart';
import 'package:intl/intl.dart';
import 'package:intl/date_symbol_data_local.dart';
import '../variable/globals.dart' as globals;
import '../classes/events.dart';
import 'ListItemMenu.dart';
void main() {
initializeDateFormatting("fr_FR", null).then((_) => (const MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
home: const ItemMenu(title: 'Flutter Demo Home Page'),
);
}
}
class ItemMenu extends StatefulWidget {
const ItemMenu({Key? key, required this.title}) : super(key: key);
// This widget is the home page of your application. It is stateful, meaning
// that it has a State object (defined below) that contains fields that affect
// how it looks.
// This class is the configuration for the state. It holds the values (in this
// case the title) provided by the parent (in this case the App widget) and
// used by the build method of the State. Fields in a Widget subclass are
// always marked "final".
final String title;
@override
State<ItemMenu> createState() => _ItemMenuState();
}
class _ItemMenuState extends State<ItemMenu> with ShowErrorDialog {
String listUser = "";
String eventName = "";
String eventStartDate = "";
String organizers = "";
String place = "";
String imgUrl = "";
Events? events;
@override
void initState() {
super.initState();
_getEventInfos();
}
Future<void> _getEventInfos() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var accessToken = prefs.getString("access_token") ?? "";
String formerName = "";
String formerDate = "";
String formerOrga = "";
String formerMap = "";
String formerImage = "";
if (accessToken.isNotEmpty) {
var urlGet = Uri.parse("${globals.api}/events/${widget.title}");
var responseGet = await http.get(urlGet,
headers: {HttpHeaders.cookieHeader: 'access_token=${accessToken}'});
stderr.writeln('Response Get status: ${responseGet.statusCode}');
if (responseGet.statusCode == 200) {
stderr.writeln('Username : ${responseGet.body}');
var events = jsonDecode(utf8.decode(responseGet.bodyBytes));
formerName = events["name"];
formerMap = events["place"];
final startDate = DateTime.parse(events["start_date"]);
final date = DateFormat.yMd().format(startDate);
final time = DateFormat.Hm().format(startDate);
final endDate = DateTime.parse(events["end_date"]);
final dateE = DateFormat.yMd().format(endDate);
final timeE = DateFormat.Hm().format(endDate);
if (events["imgUrl"] != null) {
formerImage = events["imgUrl"];
}
formerDate = "${date} ${time} à ${dateE} ${timeE}";
if (events["organizers"].length > 1) {
formerOrga = "${events['organizers'][0]}";
for (var i = 1; i < events["organizers"].length; i++) {
formerOrga = "${formerOrga}, ${events['organizers'][i]}";
}
} else {
formerOrga = "${events['organizers'][0]}";
}
} else {
var text = "";
switch (responseGet.statusCode) {
case 400:
{
text = "Requête mal construite";
}
break;
case 406:
{
text = "Mot de passe incorrect";
}
break;
case 404:
{
text = "Utilisateur inconnu";
}
break;
case 403:
{
text = "Vous n'avez pas l'autorisation de faire cette action";
}
break;
case 410:
{
text = "Token invalide";
}
break;
case 500:
{
text = "Probleme interne du serveur";
}
break;
default:
{
text = "Probleme d'authentification inconnu";
}
break;
}
showErrorDialog(context, text);
}
} else {
showErrorDialog(context, "Cache invalide");
}
setState(() {
// This call to setState tells the Flutter framework that something has
// changed in this State, which causes it to rerun the build method below
// so that the display can reflect the updated values. If we changed
// _counter without calling setState(), then the build method would not be
// called again, and so nothing would appear to happen.
eventName = formerName;
eventStartDate = formerDate;
organizers = formerOrga;
place = formerMap;
imgUrl = formerImage;
});
}
final _formKey = GlobalKey<FormState>();
@override
Widget build(BuildContext context) {
// This method is rerun every time setState is called, for instance as done
// by the _incrementCounter method above.
//
// The Flutter framework has been optimized to make rerunning build methods
// fast, so that you can just rebuild anything that needs updating rather
// than having to individually change instances of widgets.
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text("${eventName}"),
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
leading: IconButton(
icon: Icon(Icons.arrow_back),
onPressed: () {
Navigator.push(
context, MaterialPageRoute(builder: (_) => ListItemMenu()));
},
)),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Center(
child: Container(height: 250, child: Image.network(imgUrl)),
),
),
Row(
children: [
Icon(Icons.event),
Text("Date : ${eventStartDate}",
style: TextStyle(fontSize: 15.0))
],
),
Row(children: [
Icon(Icons.explore),
Text("Carte : ${place}", style: TextStyle(fontSize: 15.0))
]),
Row(children: [
Icon(Icons.group),
Text("Organisateurs : ${organizers}",
style: TextStyle(fontSize: 15.0))
]),
Row(children: [
Icon(Icons.description),
Text("Description : ", style: TextStyle(fontSize: 15.0))
])
],
)));
}
}

View File

@@ -1,135 +0,0 @@
import 'dart:convert';
import 'dart:io';
import "ItemMenu.dart";
import "Camera.dart";
import 'package:http/http.dart' as http;
import 'package:flutter/material.dart';
import '../classes/events.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:intl/intl.dart';
import 'package:intl/date_symbol_data_local.dart';
import 'package:camera/camera.dart';
import '../variable/globals.dart' as globals;
// app starting point
void main() {
initializeDateFormatting("fr_FR", null).then((_) => (const MyApp()));
}
class MyApp extends StatelessWidget {
const MyApp({super.key});
@override
Widget build(BuildContext context) {
return MaterialApp(
home: const ListItemMenu(),
debugShowCheckedModeBanner: false,
);
}
}
// homepage class
class ListItemMenu extends StatefulWidget {
const ListItemMenu({super.key});
@override
State<ListItemMenu> createState() => _MyHomePageState();
}
// homepage state
class _MyHomePageState extends State<ListItemMenu> {
// variable to call and store future list of posts
Future<List<Events>> postsFuture = getPosts();
// function to fetch data from api and return future list of posts
static Future<List<Events>> getPosts() async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var accessToken = prefs.getString("access_token") ?? "";
final List<Events> body = [];
if (accessToken.isNotEmpty) {
var url = Uri.parse("${globals.api}/events");
final response = await http.get(url, headers: {
"Content-Type": "application/json",
HttpHeaders.cookieHeader: "access_token=${accessToken}"
});
final List body = json.decode(utf8.decode(response.bodyBytes));
return body.map((e) => Events.fromJson(e)).toList();
}
return body;
}
Future<void> popCamera() async {
await availableCameras().then((value) => Navigator.push(context,
MaterialPageRoute(builder: (_) => Camera(camera: value.first))));
}
// build function
@override
Widget build(BuildContext context) {
return Scaffold(
body: Center(
// FutureBuilder
child: FutureBuilder<List<Events>>(
future: postsFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.waiting) {
// until data is fetched, show loader
return const CircularProgressIndicator();
} else if (snapshot.hasData) {
// once data is fetched, display it on screen (call buildPosts())
final posts = snapshot.data!;
return buildPosts(posts);
} else {
// if no data, show simple Text
return const Text("No data available");
}
},
),
),
);
}
// function to display fetched data on screen
Widget buildPosts(List<Events> posts) {
// ListView Builder to show data in a list
return Scaffold(
appBar: AppBar(
// Here we take the value from the MyHomePage object that was created by
// the App.build method, and use it to set our appbar title.
title: Text("Item list menu"),
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
),
body: ListView.separated(
itemCount: posts.length,
itemBuilder: (context, index) {
final post = posts[index];
final startDate = DateTime.parse(post.startDate!);
final date = DateFormat.yMd().format(startDate);
final time = DateFormat.Hm().format(startDate);
return ListTile(
title: Text('${post.name!}'),
subtitle: Text('${post.place!}\n${date} ${time}'),
onTap: () {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => ItemMenu(title: post.id!)));
});
},
separatorBuilder: (context, index) {
return Divider();
},
),
floatingActionButton: FloatingActionButton(
onPressed: popCamera,
backgroundColor: Colors.blue,
tooltip: 'Recherche',
child: const Icon(Icons.search, color: Colors.white),
),
);
}
}

View File

@@ -1,432 +0,0 @@
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
import 'package:intl/intl.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'dart:convert';
import 'dart:io';
import 'dart:typed_data';
import '../classes/alert.dart';
import '../classes/eventAdded.dart';
import '../variable/globals.dart' as globals;
void main() {
runApp(MyApp());
}
class MyApp extends StatelessWidget {
Map<String, dynamic> events = {};
String imagePath = "";
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: UpdateeventImage(events: events, imagePath: imagePath),
);
}
}
class UpdateeventImage extends StatefulWidget {
const UpdateeventImage(
{Key? key, required this.events, required this.imagePath})
: super(key: key);
final Map<String, dynamic> events;
final String imagePath;
@override
_UpdateeventImageState createState() => _UpdateeventImageState();
}
class _UpdateeventImageState extends State<UpdateeventImage>
with ShowErrorDialog, ShowEventDialog {
TextEditingController inputName = TextEditingController();
TextEditingController inputAddress = TextEditingController();
TextEditingController inputZipCode = TextEditingController();
TextEditingController inputCity = TextEditingController();
TextEditingController inputCountry = TextEditingController();
TextEditingController inputDate = TextEditingController();
TextEditingController inputDesc = TextEditingController();
TextEditingController startDatepicker = TextEditingController();
TextEditingController startTimepicker = TextEditingController();
TextEditingController endDatepicker = TextEditingController();
TextEditingController endTimepicker = TextEditingController();
onTapFunctionDatePicker(
{required BuildContext context, required String position}) async {
DateTime? pickedDate = await showDatePicker(
context: context,
firstDate: DateTime.parse(widget.events["date"]),
initialDate: DateTime.parse(widget.events["date"]),
lastDate: DateTime(2104));
if (pickedDate == null) return;
if (position == "start") {
startDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate);
}
if (position == "end") {
endDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedDate);
}
}
onTapFunctionTimePicker(
{required BuildContext context, required String position}) async {
TimeOfDay? pickedDate = await showTimePicker(
context: context,
initialTime:
TimeOfDay.fromDateTime(DateTime.parse(widget.events["date"])));
if (pickedDate == null) return;
if (position == "start") {
startTimepicker.text = pickedDate.format(context);
}
if (position == "end") {
endTimepicker.text = pickedDate.format(context);
}
}
convertNulltoEmptyString(var check) {
if (check == null) {
return "";
}
return check;
}
String formatDate(String date) {
var splitedDate = date.split("-");
var day = splitedDate[0];
var month = splitedDate[1];
var year = splitedDate[2];
return "${year}-${month}-${day}";
}
Future<void> _updateEvent(BuildContext context) async {
var url = Uri.parse("${globals.api}/token");
var name = inputName.text;
var place = inputAddress.text;
var city = inputCity.text;
var country = inputCountry.text;
var zipCode = inputZipCode.text;
var description = inputDesc.text;
var startDateFormat = formatDate(startDatepicker.text);
var endDateFormat = formatDate(endDatepicker.text);
var startDate =
"${startDateFormat}T${startTimepicker.text.replaceAll('-', ':')}";
var endDate = "${endDateFormat}T${endTimepicker.text.replaceAll('-', ':')}";
print("start date : ${startDate}");
print("end date : ${endDate}");
SharedPreferences prefs = await SharedPreferences.getInstance();
var accessToken = prefs.getString("access_token") ?? "";
List<String> send = ["toto"];
if (accessToken.isNotEmpty) {
try {
await dotenv.load();
final params = {
'expiration': '15552000',
'key': dotenv.env["IMGBB_API_KEY"],
};
print("Post Img");
final urlPost = Uri.parse('https://api.imgbb.com/1/upload')
.replace(queryParameters: params);
File image = File(widget.imagePath);
Uint8List _bytes = await image.readAsBytes();
String _base64String = base64.encode(_bytes);
final req = http.MultipartRequest('POST', urlPost)
..fields['image'] = _base64String;
final stream = await req.send();
final res = await http.Response.fromStream(stream);
final status = res.statusCode;
print("code status imgbb ${status}");
if (status == 200) {
var body = json.decode(utf8.decode(res.bodyBytes));
String imgUrl = body["data"]["url"];
//String credentials = "${pseudo}:${password}";
//Codec<String, String> stringToBase64 = utf8.fuse(base64);
//String encoded = stringToBase64.encode(credentials);
var urlPut = Uri.parse("${globals.api}/events");
var responsePut = await http.put(urlPut,
headers: {
HttpHeaders.cookieHeader: 'access_token=${accessToken}',
HttpHeaders.acceptHeader: 'application/json, text/plain, */*',
HttpHeaders.contentTypeHeader: 'application/json'
},
body: jsonEncode({
'name': name,
'place': place,
'start_date': startDate,
'end_date': endDate,
'zip_code': zipCode,
'country': country,
'city': city,
'organizers': send,
'latitude': '0.0',
'longitude': '0.0',
'description': description,
"imgUrl": imgUrl
}));
print(responsePut.statusCode);
if ((responsePut.statusCode == 200) ||
(responsePut.statusCode == 201)) {
showEventDialog(context, "Evenement ${name} ajoute");
} else {
var text = "";
switch (responsePut.statusCode) {
case 400:
{
text = "Requête mal construite";
}
break;
case 406:
{
text = "Mot de passe incorrect";
}
break;
case 404:
{
text = "Utilisateur inconnu";
}
break;
case 403:
{
text = "Utilisateur desactive";
}
break;
case 410:
{
text = "Token invalide";
}
break;
case 500:
{
text = "Probleme interne du serveur";
}
break;
default:
{
text = "Probleme d'authentification inconnu";
}
break;
}
showErrorDialog(context, text);
}
} else {
print("imgbb error : ${status}");
}
} catch (e) {
showErrorDialog(context, "${e}");
}
} else {
showErrorDialog(context, "Champ vide");
}
}
void start() async {
inputName.text = convertNulltoEmptyString(widget.events["name"]);
inputCity.text = convertNulltoEmptyString(widget.events["city"]);
inputAddress.text = convertNulltoEmptyString(widget.events["address"]);
inputZipCode.text = convertNulltoEmptyString(widget.events["zip_code"]);
inputCountry.text = convertNulltoEmptyString(widget.events["country"]);
inputDesc.text = convertNulltoEmptyString(widget.events["description"]);
DateTime pickedStartDate =
DateTime.parse(convertNulltoEmptyString(widget.events["start_date"]));
DateTime pickedEndDate =
DateTime.parse(convertNulltoEmptyString(widget.events["end_date"]));
startDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedStartDate);
endDatepicker.text = DateFormat("dd-MM-yyyy").format(pickedEndDate);
startTimepicker.text = DateFormat("HH-mm").format(pickedStartDate);
endTimepicker.text = DateFormat("HH-mm").format(pickedEndDate);
}
@override
void initState() {
start();
super.initState();
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text("Add or Update a event"),
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
),
body: SingleChildScrollView(
child: Column(
children: <Widget>[
Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Center(
child: Container(
width: 200,
height: 150,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100.0)),
child: Image.file(File(widget.imagePath))),
),
),
Padding(
//padding: const EdgeInsets.only(left:15.0,right: 15.0,top:0,bottom: 0),
padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
controller: inputName,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Nom',
hintText: 'Modifier le nom de l\'évènement'),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
controller: inputAddress,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Adresse',
hintText: 'Entrer une adresse'),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
controller: inputZipCode,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Code postal',
hintText: 'Entrer un code postal'),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
controller: inputCity,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Ville',
hintText: 'Entrer une ville'),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
controller: inputCountry,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Pays',
hintText: 'Entrer un pays'),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
controller: startDatepicker,
readOnly: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Date de debut de l\'évènement',
hintText: 'Cliquez ici pour selectionner une date'),
onTap: () => onTapFunctionDatePicker(
context: context, position: "start")),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
controller: startTimepicker,
readOnly: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Heure de debut de l\'évènement',
hintText: 'Cliquez ici pour selectionner une heure'),
onTap: () => onTapFunctionTimePicker(
context: context, position: "start")),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
controller: endDatepicker,
readOnly: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Date de fin de l\'évènement',
hintText: 'Cliquez ici pour selectionner une date'),
onTap: () => onTapFunctionDatePicker(
context: context, position: "end")),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
controller: endTimepicker,
readOnly: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Heure de fin de l\'évènement',
hintText: 'Cliquez ici pour selectionner une heure'),
onTap: () => onTapFunctionTimePicker(
context: context, position: "end")),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
controller: inputDesc,
keyboardType: TextInputType.multiline,
maxLines: 10,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Description',
hintText: 'Décrire l\'evènement'),
),
),
SizedBox(
height: 30,
),
Container(
height: 50,
width: 250,
decoration: BoxDecoration(
color: Colors.blue, borderRadius: BorderRadius.circular(20)),
child: TextButton(
onPressed: () {
_updateEvent(context);
},
child: Text(
'Ajouter',
style: TextStyle(color: Colors.white, fontSize: 25),
),
),
)
],
),
),
);
}
}

View File

@@ -1,626 +0,0 @@
# Generated by pub
# See https://dart.dev/tools/pub/glossary#lockfile
packages:
async:
dependency: transitive
description:
name: async
sha256: "947bfcf187f74dbc5e146c9eb9c0f10c9f8b30743e341481c1e2ed3ecc18c20c"
url: "https://pub.dev"
source: hosted
version: "2.11.0"
boolean_selector:
dependency: transitive
description:
name: boolean_selector
sha256: "6cfb5af12253eaf2b368f07bacc5a80d1301a071c73360d746b7f2e32d762c66"
url: "https://pub.dev"
source: hosted
version: "2.1.1"
camera:
dependency: "direct main"
description:
name: camera
sha256: "26ff41045772153f222ffffecba711a206f670f5834d40ebf5eed3811692f167"
url: "https://pub.dev"
source: hosted
version: "0.11.0+2"
camera_android_camerax:
dependency: transitive
description:
name: camera_android_camerax
sha256: "8bd9cab67551642eb33ceb33ece7acc0890014fc90ddfae637c7e2b683657e65"
url: "https://pub.dev"
source: hosted
version: "0.6.7+2"
camera_avfoundation:
dependency: transitive
description:
name: camera_avfoundation
sha256: "7c28969a975a7eb2349bc2cb2dfe3ad218a33dba9968ecfb181ce08c87486655"
url: "https://pub.dev"
source: hosted
version: "0.9.17+3"
camera_platform_interface:
dependency: transitive
description:
name: camera_platform_interface
sha256: b3ede1f171532e0d83111fe0980b46d17f1aa9788a07a2fbed07366bbdbb9061
url: "https://pub.dev"
source: hosted
version: "2.8.0"
camera_web:
dependency: "direct main"
description:
name: camera_web
sha256: "595f28c89d1fb62d77c73c633193755b781c6d2e0ebcd8dc25b763b514e6ba8f"
url: "https://pub.dev"
source: hosted
version: "0.3.5"
characters:
dependency: transitive
description:
name: characters
sha256: "04a925763edad70e8443c99234dc3328f442e811f1d8fd1a72f1c8ad0f69a605"
url: "https://pub.dev"
source: hosted
version: "1.3.0"
clock:
dependency: transitive
description:
name: clock
sha256: cb6d7f03e1de671e34607e909a7213e31d7752be4fb66a86d29fe1eb14bfb5cf
url: "https://pub.dev"
source: hosted
version: "1.1.1"
collection:
dependency: transitive
description:
name: collection
sha256: ee67cb0715911d28db6bf4af1026078bd6f0128b07a5f66fb2ed94ec6783c09a
url: "https://pub.dev"
source: hosted
version: "1.18.0"
cross_file:
dependency: transitive
description:
name: cross_file
sha256: "7caf6a750a0c04effbb52a676dce9a4a592e10ad35c34d6d2d0e4811160d5670"
url: "https://pub.dev"
source: hosted
version: "0.3.4+2"
cupertino_icons:
dependency: "direct main"
description:
name: cupertino_icons
sha256: ba631d1c7f7bef6b729a622b7b752645a2d076dba9976925b8f25725a30e1ee6
url: "https://pub.dev"
source: hosted
version: "1.0.8"
date_format_field:
dependency: "direct main"
description:
name: date_format_field
sha256: d07a428bd253454ff3123f2e57511cf6ec101d1135af3b79cebb40e1bee8bab8
url: "https://pub.dev"
source: hosted
version: "0.1.0"
dio:
dependency: transitive
description:
name: dio
sha256: e17f6b3097b8c51b72c74c9f071a605c47bcc8893839bd66732457a5ebe73714
url: "https://pub.dev"
source: hosted
version: "5.5.0+1"
dio_web_adapter:
dependency: transitive
description:
name: dio_web_adapter
sha256: "36c5b2d79eb17cdae41e974b7a8284fec631651d2a6f39a8a2ff22327e90aeac"
url: "https://pub.dev"
source: hosted
version: "1.0.1"
fake_async:
dependency: transitive
description:
name: fake_async
sha256: "511392330127add0b769b75a987850d136345d9227c6b94c96a04cf4a391bf78"
url: "https://pub.dev"
source: hosted
version: "1.3.1"
ffi:
dependency: transitive
description:
name: ffi
sha256: "493f37e7df1804778ff3a53bd691d8692ddf69702cf4c1c1096a2e41b4779e21"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
file:
dependency: transitive
description:
name: file
sha256: "5fc22d7c25582e38ad9a8515372cd9a93834027aacf1801cf01164dac0ffa08c"
url: "https://pub.dev"
source: hosted
version: "7.0.0"
file_selector_linux:
dependency: transitive
description:
name: file_selector_linux
sha256: "045d372bf19b02aeb69cacf8b4009555fb5f6f0b7ad8016e5f46dd1387ddd492"
url: "https://pub.dev"
source: hosted
version: "0.9.2+1"
file_selector_macos:
dependency: transitive
description:
name: file_selector_macos
sha256: f42eacb83b318e183b1ae24eead1373ab1334084404c8c16e0354f9a3e55d385
url: "https://pub.dev"
source: hosted
version: "0.9.4"
file_selector_platform_interface:
dependency: transitive
description:
name: file_selector_platform_interface
sha256: a3994c26f10378a039faa11de174d7b78eb8f79e4dd0af2a451410c1a5c3f66b
url: "https://pub.dev"
source: hosted
version: "2.6.2"
file_selector_windows:
dependency: transitive
description:
name: file_selector_windows
sha256: "2ad726953f6e8affbc4df8dc78b77c3b4a060967a291e528ef72ae846c60fb69"
url: "https://pub.dev"
source: hosted
version: "0.9.3+2"
flutter:
dependency: "direct main"
description: flutter
source: sdk
version: "0.0.0"
flutter_dotenv:
dependency: "direct main"
description:
name: flutter_dotenv
sha256: "9357883bdd153ab78cbf9ffa07656e336b8bbb2b5a3ca596b0b27e119f7c7d77"
url: "https://pub.dev"
source: hosted
version: "5.1.0"
flutter_gemini:
dependency: "direct main"
description:
name: flutter_gemini
sha256: "993765fafb595e5d32153f393b9c5e71f853caa5bef123d292c21f672d2b9675"
url: "https://pub.dev"
source: hosted
version: "2.0.5"
flutter_lints:
dependency: "direct dev"
description:
name: flutter_lints
sha256: "3f41d009ba7172d5ff9be5f6e6e6abb4300e263aab8866d2a0842ed2a70f8f0c"
url: "https://pub.dev"
source: hosted
version: "4.0.0"
flutter_plugin_android_lifecycle:
dependency: transitive
description:
name: flutter_plugin_android_lifecycle
sha256: "9d98bd47ef9d34e803d438f17fd32b116d31009f534a6fa5ce3a1167f189a6de"
url: "https://pub.dev"
source: hosted
version: "2.0.21"
flutter_test:
dependency: "direct dev"
description: flutter
source: sdk
version: "0.0.0"
flutter_web_plugins:
dependency: transitive
description: flutter
source: sdk
version: "0.0.0"
freezed_annotation:
dependency: transitive
description:
name: freezed_annotation
sha256: c2e2d632dd9b8a2b7751117abcfc2b4888ecfe181bd9fca7170d9ef02e595fe2
url: "https://pub.dev"
source: hosted
version: "2.4.4"
http:
dependency: "direct main"
description:
name: http
sha256: b9c29a161230ee03d3ccf545097fccd9b87a5264228c5d348202e0f0c28f9010
url: "https://pub.dev"
source: hosted
version: "1.2.2"
http_parser:
dependency: transitive
description:
name: http_parser
sha256: "2aa08ce0341cc9b354a498388e30986515406668dbcc4f7c950c3e715496693b"
url: "https://pub.dev"
source: hosted
version: "4.0.2"
image_picker:
dependency: "direct main"
description:
name: image_picker
sha256: "021834d9c0c3de46bf0fe40341fa07168407f694d9b2bb18d532dc1261867f7a"
url: "https://pub.dev"
source: hosted
version: "1.1.2"
image_picker_android:
dependency: transitive
description:
name: image_picker_android
sha256: c0e72ecd170b00a5590bb71238d57dc8ad22ee14c60c6b0d1a4e05cafbc5db4b
url: "https://pub.dev"
source: hosted
version: "0.8.12+11"
image_picker_for_web:
dependency: transitive
description:
name: image_picker_for_web
sha256: "65d94623e15372c5c51bebbcb820848d7bcb323836e12dfdba60b5d3a8b39e50"
url: "https://pub.dev"
source: hosted
version: "3.0.5"
image_picker_ios:
dependency: transitive
description:
name: image_picker_ios
sha256: "6703696ad49f5c3c8356d576d7ace84d1faf459afb07accbb0fae780753ff447"
url: "https://pub.dev"
source: hosted
version: "0.8.12"
image_picker_linux:
dependency: transitive
description:
name: image_picker_linux
sha256: "4ed1d9bb36f7cd60aa6e6cd479779cc56a4cb4e4de8f49d487b1aaad831300fa"
url: "https://pub.dev"
source: hosted
version: "0.2.1+1"
image_picker_macos:
dependency: transitive
description:
name: image_picker_macos
sha256: "3f5ad1e8112a9a6111c46d0b57a7be2286a9a07fc6e1976fdf5be2bd31d4ff62"
url: "https://pub.dev"
source: hosted
version: "0.2.1+1"
image_picker_platform_interface:
dependency: transitive
description:
name: image_picker_platform_interface
sha256: "9ec26d410ff46f483c5519c29c02ef0e02e13a543f882b152d4bfd2f06802f80"
url: "https://pub.dev"
source: hosted
version: "2.10.0"
image_picker_windows:
dependency: transitive
description:
name: image_picker_windows
sha256: "6ad07afc4eb1bc25f3a01084d28520496c4a3bb0cb13685435838167c9dcedeb"
url: "https://pub.dev"
source: hosted
version: "0.2.1+1"
intl:
dependency: "direct main"
description:
name: intl
sha256: d6f56758b7d3014a48af9701c085700aac781a92a87a62b1333b46d8879661cf
url: "https://pub.dev"
source: hosted
version: "0.19.0"
json_annotation:
dependency: transitive
description:
name: json_annotation
sha256: "1ce844379ca14835a50d2f019a3099f419082cfdd231cd86a142af94dd5c6bb1"
url: "https://pub.dev"
source: hosted
version: "4.9.0"
leak_tracker:
dependency: transitive
description:
name: leak_tracker
sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05"
url: "https://pub.dev"
source: hosted
version: "10.0.5"
leak_tracker_flutter_testing:
dependency: transitive
description:
name: leak_tracker_flutter_testing
sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806"
url: "https://pub.dev"
source: hosted
version: "3.0.5"
leak_tracker_testing:
dependency: transitive
description:
name: leak_tracker_testing
sha256: "6ba465d5d76e67ddf503e1161d1f4a6bc42306f9d66ca1e8f079a47290fb06d3"
url: "https://pub.dev"
source: hosted
version: "3.0.1"
lints:
dependency: transitive
description:
name: lints
sha256: "976c774dd944a42e83e2467f4cc670daef7eed6295b10b36ae8c85bcbf828235"
url: "https://pub.dev"
source: hosted
version: "4.0.0"
matcher:
dependency: transitive
description:
name: matcher
sha256: d2323aa2060500f906aa31a895b4030b6da3ebdcc5619d14ce1aada65cd161cb
url: "https://pub.dev"
source: hosted
version: "0.12.16+1"
material_color_utilities:
dependency: transitive
description:
name: material_color_utilities
sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec
url: "https://pub.dev"
source: hosted
version: "0.11.1"
meta:
dependency: transitive
description:
name: meta
sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7
url: "https://pub.dev"
source: hosted
version: "1.15.0"
mime:
dependency: transitive
description:
name: mime
sha256: "2e123074287cc9fd6c09de8336dae606d1ddb88d9ac47358826db698c176a1f2"
url: "https://pub.dev"
source: hosted
version: "1.0.5"
path:
dependency: "direct main"
description:
name: path
sha256: "087ce49c3f0dc39180befefc60fdb4acd8f8620e5682fe2476afd0b3688bb4af"
url: "https://pub.dev"
source: hosted
version: "1.9.0"
path_provider:
dependency: "direct main"
description:
name: path_provider
sha256: fec0d61223fba3154d87759e3cc27fe2c8dc498f6386c6d6fc80d1afdd1bf378
url: "https://pub.dev"
source: hosted
version: "2.1.4"
path_provider_android:
dependency: transitive
description:
name: path_provider_android
sha256: "490539678396d4c3c0b06efdaab75ae60675c3e0c66f72bc04c2e2c1e0e2abeb"
url: "https://pub.dev"
source: hosted
version: "2.2.9"
path_provider_foundation:
dependency: transitive
description:
name: path_provider_foundation
sha256: f234384a3fdd67f989b4d54a5d73ca2a6c422fa55ae694381ae0f4375cd1ea16
url: "https://pub.dev"
source: hosted
version: "2.4.0"
path_provider_linux:
dependency: transitive
description:
name: path_provider_linux
sha256: f7a1fe3a634fe7734c8d3f2766ad746ae2a2884abe22e241a8b301bf5cac3279
url: "https://pub.dev"
source: hosted
version: "2.2.1"
path_provider_platform_interface:
dependency: transitive
description:
name: path_provider_platform_interface
sha256: "88f5779f72ba699763fa3a3b06aa4bf6de76c8e5de842cf6f29e2e06476c2334"
url: "https://pub.dev"
source: hosted
version: "2.1.2"
path_provider_windows:
dependency: transitive
description:
name: path_provider_windows
sha256: bd6f00dbd873bfb70d0761682da2b3a2c2fccc2b9e84c495821639601d81afe7
url: "https://pub.dev"
source: hosted
version: "2.3.0"
platform:
dependency: transitive
description:
name: platform
sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65"
url: "https://pub.dev"
source: hosted
version: "3.1.5"
plugin_platform_interface:
dependency: transitive
description:
name: plugin_platform_interface
sha256: "4820fbfdb9478b1ebae27888254d445073732dae3d6ea81f0b7e06d5dedc3f02"
url: "https://pub.dev"
source: hosted
version: "2.1.8"
shared_preferences:
dependency: "direct main"
description:
name: shared_preferences
sha256: c272f9cabca5a81adc9b0894381e9c1def363e980f960fa903c604c471b22f68
url: "https://pub.dev"
source: hosted
version: "2.3.1"
shared_preferences_android:
dependency: transitive
description:
name: shared_preferences_android
sha256: a7e8467e9181cef109f601e3f65765685786c1a738a83d7fbbde377589c0d974
url: "https://pub.dev"
source: hosted
version: "2.3.1"
shared_preferences_foundation:
dependency: transitive
description:
name: shared_preferences_foundation
sha256: "776786cff96324851b656777648f36ac772d88bc4c669acff97b7fce5de3c849"
url: "https://pub.dev"
source: hosted
version: "2.5.1"
shared_preferences_linux:
dependency: transitive
description:
name: shared_preferences_linux
sha256: "580abfd40f415611503cae30adf626e6656dfb2f0cee8f465ece7b6defb40f2f"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
shared_preferences_platform_interface:
dependency: transitive
description:
name: shared_preferences_platform_interface
sha256: "57cbf196c486bc2cf1f02b85784932c6094376284b3ad5779d1b1c6c6a816b80"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
shared_preferences_web:
dependency: transitive
description:
name: shared_preferences_web
sha256: d2ca4132d3946fec2184261726b355836a82c33d7d5b67af32692aff18a4684e
url: "https://pub.dev"
source: hosted
version: "2.4.2"
shared_preferences_windows:
dependency: transitive
description:
name: shared_preferences_windows
sha256: "94ef0f72b2d71bc3e700e025db3710911bd51a71cefb65cc609dd0d9a982e3c1"
url: "https://pub.dev"
source: hosted
version: "2.4.1"
sky_engine:
dependency: transitive
description: flutter
source: sdk
version: "0.0.99"
source_span:
dependency: transitive
description:
name: source_span
sha256: "53e943d4206a5e30df338fd4c6e7a077e02254531b138a15aec3bd143c1a8b3c"
url: "https://pub.dev"
source: hosted
version: "1.10.0"
stack_trace:
dependency: transitive
description:
name: stack_trace
sha256: "73713990125a6d93122541237550ee3352a2d84baad52d375a4cad2eb9b7ce0b"
url: "https://pub.dev"
source: hosted
version: "1.11.1"
stream_channel:
dependency: transitive
description:
name: stream_channel
sha256: ba2aa5d8cc609d96bbb2899c28934f9e1af5cddbd60a827822ea467161eb54e7
url: "https://pub.dev"
source: hosted
version: "2.1.2"
stream_transform:
dependency: transitive
description:
name: stream_transform
sha256: "14a00e794c7c11aa145a170587321aedce29769c08d7f58b1d141da75e3b1c6f"
url: "https://pub.dev"
source: hosted
version: "2.1.0"
string_scanner:
dependency: transitive
description:
name: string_scanner
sha256: "556692adab6cfa87322a115640c11f13cb77b3f076ddcc5d6ae3c20242bedcde"
url: "https://pub.dev"
source: hosted
version: "1.2.0"
term_glyph:
dependency: transitive
description:
name: term_glyph
sha256: a29248a84fbb7c79282b40b8c72a1209db169a2e0542bce341da992fe1bc7e84
url: "https://pub.dev"
source: hosted
version: "1.2.1"
test_api:
dependency: transitive
description:
name: test_api
sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb"
url: "https://pub.dev"
source: hosted
version: "0.7.2"
typed_data:
dependency: transitive
description:
name: typed_data
sha256: facc8d6582f16042dd49f2463ff1bd6e2c9ef9f3d5da3d9b087e244a7b564b3c
url: "https://pub.dev"
source: hosted
version: "1.3.2"
vector_math:
dependency: transitive
description:
name: vector_math
sha256: "80b3257d1492ce4d091729e3a67a60407d227c27241d6927be0130c98e741803"
url: "https://pub.dev"
source: hosted
version: "2.1.4"
vm_service:
dependency: transitive
description:
name: vm_service
sha256: "5c5f338a667b4c644744b661f309fb8080bb94b18a7e91ef1dbd343bed00ed6d"
url: "https://pub.dev"
source: hosted
version: "14.2.5"
web:
dependency: transitive
description:
name: web
sha256: d43c1d6b787bf0afad444700ae7f4db8827f701bc61c255ac8d328c6f4d52062
url: "https://pub.dev"
source: hosted
version: "1.0.0"
xdg_directories:
dependency: transitive
description:
name: xdg_directories
sha256: faea9dee56b520b55a566385b84f2e8de55e7496104adada9962e0bd11bcff1d
url: "https://pub.dev"
source: hosted
version: "1.0.4"
sdks:
dart: ">=3.4.0 <4.0.0"
flutter: ">=3.22.0"

View File

@@ -1,14 +0,0 @@
//
// Generated file. Do not edit.
//
// clang-format off
#include "generated_plugin_registrant.h"
#include <file_selector_windows/file_selector_windows.h>
void RegisterPlugins(flutter::PluginRegistry* registry) {
FileSelectorWindowsRegisterWithRegistrar(
registry->GetRegistrarForPlugin("FileSelectorWindows"));
}

View File

@@ -0,0 +1,45 @@
# This file tracks properties of this Flutter project.
# Used by Flutter tool to assess capabilities and perform upgrades etc.
#
# This file should be version controlled and should not be manually edited.
version:
revision: "05db9689081f091050f01aed79f04dce0c750154"
channel: "stable"
project_type: app
# Tracks metadata for the flutter migrate command
migration:
platforms:
- platform: root
create_revision: 05db9689081f091050f01aed79f04dce0c750154
base_revision: 05db9689081f091050f01aed79f04dce0c750154
- platform: android
create_revision: 05db9689081f091050f01aed79f04dce0c750154
base_revision: 05db9689081f091050f01aed79f04dce0c750154
- platform: ios
create_revision: 05db9689081f091050f01aed79f04dce0c750154
base_revision: 05db9689081f091050f01aed79f04dce0c750154
- platform: linux
create_revision: 05db9689081f091050f01aed79f04dce0c750154
base_revision: 05db9689081f091050f01aed79f04dce0c750154
- platform: macos
create_revision: 05db9689081f091050f01aed79f04dce0c750154
base_revision: 05db9689081f091050f01aed79f04dce0c750154
- platform: web
create_revision: 05db9689081f091050f01aed79f04dce0c750154
base_revision: 05db9689081f091050f01aed79f04dce0c750154
- platform: windows
create_revision: 05db9689081f091050f01aed79f04dce0c750154
base_revision: 05db9689081f091050f01aed79f04dce0c750154
# User provided section
# List of Local paths (relative to this file) that should be
# ignored by the migrate tool.
#
# Files that are not part of the templates will be ignored by default.
unmanaged_files:
- 'lib/main.dart'
- 'ios/Runner.xcodeproj/project.pbxproj'

View File

@@ -0,0 +1,16 @@
# covas_mobile_new
A new Flutter project.
## Getting Started
This project is a starting point for a Flutter application.
A few resources to get you started if this is your first Flutter project:
- [Lab: Write your first Flutter app](https://docs.flutter.dev/get-started/codelab)
- [Cookbook: Useful Flutter samples](https://docs.flutter.dev/cookbook)
For help getting started with Flutter development, view the
[online documentation](https://docs.flutter.dev/), which offers tutorials,
samples, guidance on mobile development, and a full API reference.

View File

@@ -0,0 +1,28 @@
# This file configures the analyzer, which statically analyzes Dart code to
# check for errors, warnings, and lints.
#
# The issues identified by the analyzer are surfaced in the UI of Dart-enabled
# IDEs (https://dart.dev/tools#ides-and-editors). The analyzer can also be
# invoked from the command line by running `flutter analyze`.
# The following line activates a set of recommended lints for Flutter apps,
# packages, and plugins designed to encourage good coding practices.
include: package:flutter_lints/flutter.yaml
linter:
# The lint rules applied to this project can be customized in the
# section below to disable rules from the `package:flutter_lints/flutter.yaml`
# included above or to enable additional rules. A list of all available lints
# and their documentation is published at https://dart.dev/lints.
#
# Instead of disabling a lint rule for the entire project in the
# section below, it can also be suppressed for a single line of code
# or a specific dart file by using the `// ignore: name_of_lint` and
# `// ignore_for_file: name_of_lint` syntax on the line or in the file
# producing the lint.
rules:
# avoid_print: false # Uncomment to disable the `avoid_print` rule
# prefer_single_quotes: true # Uncomment to enable the `prefer_single_quotes` rule
# Additional information about this file can be found at
# https://dart.dev/guides/language/analysis-options

14
covas_mobile_new/android/.gitignore vendored Normal file
View File

@@ -0,0 +1,14 @@
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
.cxx/
# Remember to never publicly share your keystore.
# See https://flutter.dev/to/reference-keystore
key.properties
**/*.keystore
**/*.jks

View File

@@ -0,0 +1,49 @@
plugins {
id("com.android.application")
id("kotlin-android")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")
}
android {
namespace = "com.example.covas_mobile_new"
compileSdk = flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
isCoreLibraryDesugaringEnabled = true
}
kotlinOptions {
jvmTarget = JavaVersion.VERSION_11.toString()
}
defaultConfig {
// TODO: Specify your own unique Application ID (https://developer.android.com/studio/build/application-id.html).
applicationId = "com.example.covas_mobile_new"
// You can update the following values to match your application needs.
// For more information, see: https://flutter.dev/to/review-gradle-config.
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
}
buildTypes {
release {
// TODO: Add your own signing config for the release build.
// Signing with the debug keys for now, so `flutter run --release` works.
signingConfig = signingConfigs.getByName("debug")
}
}
}
dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4")
}
flutter {
source = "../.."
}

View File

@@ -1,5 +1,4 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.example.covas_mobile">
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.

View File

@@ -0,0 +1,53 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION"/>
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION"/>
<application
android:label="covas_mobile_new"
android:name="${applicationName}"
android:icon="@mipmap/ic_launcher">
<meta-data
android:name="com.google.android.gms.ads.APPLICATION_ID"
android:value="ca-app-pub-4855855675386260~3438207239"/>
<activity
android:name=".MainActivity"
android:exported="true"
android:launchMode="singleTop"
android:taskAffinity=""
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:enableOnBackInvokedCallback="true"
android:windowSoftInputMode="adjustResize">
<!-- Specifies an Android theme to apply to this Activity as soon as
the Android process has started. This theme is visible to the user
while the Flutter UI initializes. After that, this theme continues
to determine the Window background behind the Flutter UI. -->
<meta-data
android:name="io.flutter.embedding.android.NormalTheme"
android:resource="@style/NormalTheme"
/>
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
</activity>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
</application>
<!-- Required to query activities that can process text, see:
https://developer.android.com/training/package-visibility and
https://developer.android.com/reference/android/content/Intent#ACTION_PROCESS_TEXT.
In particular, this is used by the Flutter engine in io.flutter.plugin.text.ProcessTextPlugin. -->
<queries>
<intent>
<action android:name="android.intent.action.PROCESS_TEXT"/>
<data android:mimeType="text/plain"/>
</intent>
</queries>
</manifest>

View File

@@ -0,0 +1,5 @@
package com.example.covas_mobile_new
import io.flutter.embedding.android.FlutterActivity
class MainActivity : FlutterActivity()

View File

Before

Width:  |  Height:  |  Size: 544 B

After

Width:  |  Height:  |  Size: 544 B

View File

Before

Width:  |  Height:  |  Size: 442 B

After

Width:  |  Height:  |  Size: 442 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.4 KiB

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -0,0 +1,7 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android">
<!-- The INTERNET permission is required for development. Specifically,
the Flutter tool needs it to communicate with the running application
to allow setting breakpoints, to provide hot reload, etc.
-->
<uses-permission android:name="android.permission.INTERNET"/>
</manifest>

View File

@@ -0,0 +1,24 @@
allprojects {
repositories {
google()
mavenCentral()
}
}
val newBuildDir: Directory =
rootProject.layout.buildDirectory
.dir("../../build")
.get()
rootProject.layout.buildDirectory.value(newBuildDir)
subprojects {
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
project.layout.buildDirectory.value(newSubprojectBuildDir)
}
subprojects {
project.evaluationDependsOn(":app")
}
tasks.register<Delete>("clean") {
delete(rootProject.layout.buildDirectory)
}

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,3 @@
org.gradle.jvmargs=-Xmx8G -XX:MaxMetaspaceSize=4G -XX:ReservedCodeCacheSize=512m -XX:+HeapDumpOnOutOfMemoryError
android.useAndroidX=true
android.enableJetifier=true

View File

@@ -0,0 +1,5 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-8.12-all.zip

View File

@@ -0,0 +1,26 @@
pluginManagement {
val flutterSdkPath =
run {
val properties = java.util.Properties()
file("local.properties").inputStream().use { properties.load(it) }
val flutterSdkPath = properties.getProperty("flutter.sdk")
require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
flutterSdkPath
}
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
id("com.android.application") version "8.9.1" apply false
id("org.jetbrains.kotlin.android") version "2.1.0" apply false
}
include(":app")

View File

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 36 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 11 KiB

View File

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@@ -0,0 +1,26 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>CFBundleDevelopmentRegion</key>
<string>en</string>
<key>CFBundleExecutable</key>
<string>App</string>
<key>CFBundleIdentifier</key>
<string>io.flutter.flutter.app</string>
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>App</string>
<key>CFBundlePackageType</key>
<string>FMWK</string>
<key>CFBundleShortVersionString</key>
<string>1.0</string>
<key>CFBundleSignature</key>
<string>????</string>
<key>CFBundleVersion</key>
<string>1.0</string>
<key>MinimumOSVersion</key>
<string>13.0</string>
</dict>
</plist>

View File

@@ -0,0 +1,616 @@
// !$*UTF8*$!
{
archiveVersion = 1;
classes = {
};
objectVersion = 54;
objects = {
/* Begin PBXBuildFile section */
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */ = {isa = PBXBuildFile; fileRef = 1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */; };
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */ = {isa = PBXBuildFile; fileRef = 331C807B294A618700263BE5 /* RunnerTests.swift */; };
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */ = {isa = PBXBuildFile; fileRef = 3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */; };
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */ = {isa = PBXBuildFile; fileRef = 74858FAE1ED2DC5600515810 /* AppDelegate.swift */; };
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FA1CF9000F007C117D /* Main.storyboard */; };
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FD1CF9000F007C117D /* Assets.xcassets */; };
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */ = {isa = PBXBuildFile; fileRef = 97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */; };
/* End PBXBuildFile section */
/* Begin PBXContainerItemProxy section */
331C8085294A63A400263BE5 /* PBXContainerItemProxy */ = {
isa = PBXContainerItemProxy;
containerPortal = 97C146E61CF9000F007C117D /* Project object */;
proxyType = 1;
remoteGlobalIDString = 97C146ED1CF9000F007C117D;
remoteInfo = Runner;
};
/* End PBXContainerItemProxy section */
/* Begin PBXCopyFilesBuildPhase section */
9705A1C41CF9048500538489 /* Embed Frameworks */ = {
isa = PBXCopyFilesBuildPhase;
buildActionMask = 2147483647;
dstPath = "";
dstSubfolderSpec = 10;
files = (
);
name = "Embed Frameworks";
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXCopyFilesBuildPhase section */
/* Begin PBXFileReference section */
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = GeneratedPluginRegistrant.h; sourceTree = "<group>"; };
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = GeneratedPluginRegistrant.m; sourceTree = "<group>"; };
331C807B294A618700263BE5 /* RunnerTests.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = RunnerTests.swift; sourceTree = "<group>"; };
331C8081294A63A400263BE5 /* RunnerTests.xctest */ = {isa = PBXFileReference; explicitFileType = wrapper.cfbundle; includeInIndex = 0; path = RunnerTests.xctest; sourceTree = BUILT_PRODUCTS_DIR; };
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = AppFrameworkInfo.plist; path = Flutter/AppFrameworkInfo.plist; sourceTree = "<group>"; };
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = "Runner-Bridging-Header.h"; sourceTree = "<group>"; };
74858FAE1ED2DC5600515810 /* AppDelegate.swift */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.swift; path = AppDelegate.swift; sourceTree = "<group>"; };
7AFA3C8E1D35360C0083082E /* Release.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; name = Release.xcconfig; path = Flutter/Release.xcconfig; sourceTree = "<group>"; };
9740EEB21CF90195004384FC /* Debug.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Debug.xcconfig; path = Flutter/Debug.xcconfig; sourceTree = "<group>"; };
9740EEB31CF90195004384FC /* Generated.xcconfig */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.xcconfig; name = Generated.xcconfig; path = Flutter/Generated.xcconfig; sourceTree = "<group>"; };
97C146EE1CF9000F007C117D /* Runner.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = Runner.app; sourceTree = BUILT_PRODUCTS_DIR; };
97C146FB1CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/Main.storyboard; sourceTree = "<group>"; };
97C146FD1CF9000F007C117D /* Assets.xcassets */ = {isa = PBXFileReference; lastKnownFileType = folder.assetcatalog; path = Assets.xcassets; sourceTree = "<group>"; };
97C147001CF9000F007C117D /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.storyboard; name = Base; path = Base.lproj/LaunchScreen.storyboard; sourceTree = "<group>"; };
97C147021CF9000F007C117D /* Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = Info.plist; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
97C146EB1CF9000F007C117D /* Frameworks */ = {
isa = PBXFrameworksBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXFrameworksBuildPhase section */
/* Begin PBXGroup section */
331C8082294A63A400263BE5 /* RunnerTests */ = {
isa = PBXGroup;
children = (
331C807B294A618700263BE5 /* RunnerTests.swift */,
);
path = RunnerTests;
sourceTree = "<group>";
};
9740EEB11CF90186004384FC /* Flutter */ = {
isa = PBXGroup;
children = (
3B3967151E833CAA004F5970 /* AppFrameworkInfo.plist */,
9740EEB21CF90195004384FC /* Debug.xcconfig */,
7AFA3C8E1D35360C0083082E /* Release.xcconfig */,
9740EEB31CF90195004384FC /* Generated.xcconfig */,
);
name = Flutter;
sourceTree = "<group>";
};
97C146E51CF9000F007C117D = {
isa = PBXGroup;
children = (
9740EEB11CF90186004384FC /* Flutter */,
97C146F01CF9000F007C117D /* Runner */,
97C146EF1CF9000F007C117D /* Products */,
331C8082294A63A400263BE5 /* RunnerTests */,
);
sourceTree = "<group>";
};
97C146EF1CF9000F007C117D /* Products */ = {
isa = PBXGroup;
children = (
97C146EE1CF9000F007C117D /* Runner.app */,
331C8081294A63A400263BE5 /* RunnerTests.xctest */,
);
name = Products;
sourceTree = "<group>";
};
97C146F01CF9000F007C117D /* Runner */ = {
isa = PBXGroup;
children = (
97C146FA1CF9000F007C117D /* Main.storyboard */,
97C146FD1CF9000F007C117D /* Assets.xcassets */,
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */,
97C147021CF9000F007C117D /* Info.plist */,
1498D2321E8E86230040F4C2 /* GeneratedPluginRegistrant.h */,
1498D2331E8E89220040F4C2 /* GeneratedPluginRegistrant.m */,
74858FAE1ED2DC5600515810 /* AppDelegate.swift */,
74858FAD1ED2DC5600515810 /* Runner-Bridging-Header.h */,
);
path = Runner;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
331C8080294A63A400263BE5 /* RunnerTests */ = {
isa = PBXNativeTarget;
buildConfigurationList = 331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */;
buildPhases = (
331C807D294A63A400263BE5 /* Sources */,
331C807F294A63A400263BE5 /* Resources */,
);
buildRules = (
);
dependencies = (
331C8086294A63A400263BE5 /* PBXTargetDependency */,
);
name = RunnerTests;
productName = RunnerTests;
productReference = 331C8081294A63A400263BE5 /* RunnerTests.xctest */;
productType = "com.apple.product-type.bundle.unit-test";
};
97C146ED1CF9000F007C117D /* Runner */ = {
isa = PBXNativeTarget;
buildConfigurationList = 97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */;
buildPhases = (
9740EEB61CF901F6004384FC /* Run Script */,
97C146EA1CF9000F007C117D /* Sources */,
97C146EB1CF9000F007C117D /* Frameworks */,
97C146EC1CF9000F007C117D /* Resources */,
9705A1C41CF9048500538489 /* Embed Frameworks */,
3B06AD1E1E4923F5004D2608 /* Thin Binary */,
);
buildRules = (
);
dependencies = (
);
name = Runner;
productName = Runner;
productReference = 97C146EE1CF9000F007C117D /* Runner.app */;
productType = "com.apple.product-type.application";
};
/* End PBXNativeTarget section */
/* Begin PBXProject section */
97C146E61CF9000F007C117D /* Project object */ = {
isa = PBXProject;
attributes = {
BuildIndependentTargetsInParallel = YES;
LastUpgradeCheck = 1510;
ORGANIZATIONNAME = "";
TargetAttributes = {
331C8080294A63A400263BE5 = {
CreatedOnToolsVersion = 14.0;
TestTargetID = 97C146ED1CF9000F007C117D;
};
97C146ED1CF9000F007C117D = {
CreatedOnToolsVersion = 7.3.1;
LastSwiftMigration = 1100;
};
};
};
buildConfigurationList = 97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */;
compatibilityVersion = "Xcode 9.3";
developmentRegion = en;
hasScannedForEncodings = 0;
knownRegions = (
en,
Base,
);
mainGroup = 97C146E51CF9000F007C117D;
productRefGroup = 97C146EF1CF9000F007C117D /* Products */;
projectDirPath = "";
projectRoot = "";
targets = (
97C146ED1CF9000F007C117D /* Runner */,
331C8080294A63A400263BE5 /* RunnerTests */,
);
};
/* End PBXProject section */
/* Begin PBXResourcesBuildPhase section */
331C807F294A63A400263BE5 /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EC1CF9000F007C117D /* Resources */ = {
isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647;
files = (
97C147011CF9000F007C117D /* LaunchScreen.storyboard in Resources */,
3B3967161E833CAA004F5970 /* AppFrameworkInfo.plist in Resources */,
97C146FE1CF9000F007C117D /* Assets.xcassets in Resources */,
97C146FC1CF9000F007C117D /* Main.storyboard in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXResourcesBuildPhase section */
/* Begin PBXShellScriptBuildPhase section */
3B06AD1E1E4923F5004D2608 /* Thin Binary */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
"${TARGET_BUILD_DIR}/${INFOPLIST_PATH}",
);
name = "Thin Binary";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" embed_and_thin";
};
9740EEB61CF901F6004384FC /* Run Script */ = {
isa = PBXShellScriptBuildPhase;
alwaysOutOfDate = 1;
buildActionMask = 2147483647;
files = (
);
inputPaths = (
);
name = "Run Script";
outputPaths = (
);
runOnlyForDeploymentPostprocessing = 0;
shellPath = /bin/sh;
shellScript = "/bin/sh \"$FLUTTER_ROOT/packages/flutter_tools/bin/xcode_backend.sh\" build";
};
/* End PBXShellScriptBuildPhase section */
/* Begin PBXSourcesBuildPhase section */
331C807D294A63A400263BE5 /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
331C808B294A63AB00263BE5 /* RunnerTests.swift in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
97C146EA1CF9000F007C117D /* Sources */ = {
isa = PBXSourcesBuildPhase;
buildActionMask = 2147483647;
files = (
74858FAF1ED2DC5600515810 /* AppDelegate.swift in Sources */,
1498D2341E8E89220040F4C2 /* GeneratedPluginRegistrant.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
/* End PBXSourcesBuildPhase section */
/* Begin PBXTargetDependency section */
331C8086294A63A400263BE5 /* PBXTargetDependency */ = {
isa = PBXTargetDependency;
target = 97C146ED1CF9000F007C117D /* Runner */;
targetProxy = 331C8085294A63A400263BE5 /* PBXContainerItemProxy */;
};
/* End PBXTargetDependency section */
/* Begin PBXVariantGroup section */
97C146FA1CF9000F007C117D /* Main.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C146FB1CF9000F007C117D /* Base */,
);
name = Main.storyboard;
sourceTree = "<group>";
};
97C146FF1CF9000F007C117D /* LaunchScreen.storyboard */ = {
isa = PBXVariantGroup;
children = (
97C147001CF9000F007C117D /* Base */,
);
name = LaunchScreen.storyboard;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */
249021D3217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Profile;
};
249021D4217E4FDB00AE95B9 /* Profile */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.covasMobileNew;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Profile;
};
331C8088294A63A400263BE5 /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.covasMobileNew.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Debug;
};
331C8089294A63A400263BE5 /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.covasMobileNew.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Release;
};
331C808A294A63A400263BE5 /* Profile */ = {
isa = XCBuildConfiguration;
buildSettings = {
BUNDLE_LOADER = "$(TEST_HOST)";
CODE_SIGN_STYLE = Automatic;
CURRENT_PROJECT_VERSION = 1;
GENERATE_INFOPLIST_FILE = YES;
MARKETING_VERSION = 1.0;
PRODUCT_BUNDLE_IDENTIFIER = com.example.covasMobileNew.RunnerTests;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_VERSION = 5.0;
TEST_HOST = "$(BUILT_PRODUCTS_DIR)/Runner.app/$(BUNDLE_EXECUTABLE_FOLDER_PATH)/Runner";
};
name = Profile;
};
97C147031CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = dwarf;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_TESTABILITY = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_DYNAMIC_NO_PIC = NO;
GCC_NO_COMMON_BLOCKS = YES;
GCC_OPTIMIZATION_LEVEL = 0;
GCC_PREPROCESSOR_DEFINITIONS = (
"DEBUG=1",
"$(inherited)",
);
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = YES;
ONLY_ACTIVE_ARCH = YES;
SDKROOT = iphoneos;
TARGETED_DEVICE_FAMILY = "1,2";
};
name = Debug;
};
97C147041CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
buildSettings = {
ALWAYS_SEARCH_USER_PATHS = NO;
ASSETCATALOG_COMPILER_GENERATE_SWIFT_ASSET_SYMBOL_EXTENSIONS = YES;
CLANG_ANALYZER_NONNULL = YES;
CLANG_CXX_LANGUAGE_STANDARD = "gnu++0x";
CLANG_CXX_LIBRARY = "libc++";
CLANG_ENABLE_MODULES = YES;
CLANG_ENABLE_OBJC_ARC = YES;
CLANG_WARN_BLOCK_CAPTURE_AUTORELEASING = YES;
CLANG_WARN_BOOL_CONVERSION = YES;
CLANG_WARN_COMMA = YES;
CLANG_WARN_CONSTANT_CONVERSION = YES;
CLANG_WARN_DEPRECATED_OBJC_IMPLEMENTATIONS = YES;
CLANG_WARN_DIRECT_OBJC_ISA_USAGE = YES_ERROR;
CLANG_WARN_EMPTY_BODY = YES;
CLANG_WARN_ENUM_CONVERSION = YES;
CLANG_WARN_INFINITE_RECURSION = YES;
CLANG_WARN_INT_CONVERSION = YES;
CLANG_WARN_NON_LITERAL_NULL_CONVERSION = YES;
CLANG_WARN_OBJC_IMPLICIT_RETAIN_SELF = YES;
CLANG_WARN_OBJC_LITERAL_CONVERSION = YES;
CLANG_WARN_OBJC_ROOT_CLASS = YES_ERROR;
CLANG_WARN_RANGE_LOOP_ANALYSIS = YES;
CLANG_WARN_STRICT_PROTOTYPES = YES;
CLANG_WARN_SUSPICIOUS_MOVE = YES;
CLANG_WARN_UNREACHABLE_CODE = YES;
CLANG_WARN__DUPLICATE_METHOD_MATCH = YES;
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
COPY_PHASE_STRIP = NO;
DEBUG_INFORMATION_FORMAT = "dwarf-with-dsym";
ENABLE_NS_ASSERTIONS = NO;
ENABLE_STRICT_OBJC_MSGSEND = YES;
ENABLE_USER_SCRIPT_SANDBOXING = NO;
GCC_C_LANGUAGE_STANDARD = gnu99;
GCC_NO_COMMON_BLOCKS = YES;
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
GCC_WARN_UNDECLARED_SELECTOR = YES;
GCC_WARN_UNINITIALIZED_AUTOS = YES_AGGRESSIVE;
GCC_WARN_UNUSED_FUNCTION = YES;
GCC_WARN_UNUSED_VARIABLE = YES;
IPHONEOS_DEPLOYMENT_TARGET = 13.0;
MTL_ENABLE_DEBUG_INFO = NO;
SDKROOT = iphoneos;
SUPPORTED_PLATFORMS = iphoneos;
SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_OPTIMIZATION_LEVEL = "-O";
TARGETED_DEVICE_FAMILY = "1,2";
VALIDATE_PRODUCT = YES;
};
name = Release;
};
97C147061CF9000F007C117D /* Debug */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 9740EEB21CF90195004384FC /* Debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.covasMobileNew;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_OPTIMIZATION_LEVEL = "-Onone";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Debug;
};
97C147071CF9000F007C117D /* Release */ = {
isa = XCBuildConfiguration;
baseConfigurationReference = 7AFA3C8E1D35360C0083082E /* Release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CLANG_ENABLE_MODULES = YES;
CURRENT_PROJECT_VERSION = "$(FLUTTER_BUILD_NUMBER)";
ENABLE_BITCODE = NO;
INFOPLIST_FILE = Runner/Info.plist;
LD_RUNPATH_SEARCH_PATHS = (
"$(inherited)",
"@executable_path/Frameworks",
);
PRODUCT_BUNDLE_IDENTIFIER = com.example.covasMobileNew;
PRODUCT_NAME = "$(TARGET_NAME)";
SWIFT_OBJC_BRIDGING_HEADER = "Runner/Runner-Bridging-Header.h";
SWIFT_VERSION = 5.0;
VERSIONING_SYSTEM = "apple-generic";
};
name = Release;
};
/* End XCBuildConfiguration section */
/* Begin XCConfigurationList section */
331C8087294A63A400263BE5 /* Build configuration list for PBXNativeTarget "RunnerTests" */ = {
isa = XCConfigurationList;
buildConfigurations = (
331C8088294A63A400263BE5 /* Debug */,
331C8089294A63A400263BE5 /* Release */,
331C808A294A63A400263BE5 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C146E91CF9000F007C117D /* Build configuration list for PBXProject "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147031CF9000F007C117D /* Debug */,
97C147041CF9000F007C117D /* Release */,
249021D3217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
97C147051CF9000F007C117D /* Build configuration list for PBXNativeTarget "Runner" */ = {
isa = XCConfigurationList;
buildConfigurations = (
97C147061CF9000F007C117D /* Debug */,
97C147071CF9000F007C117D /* Release */,
249021D4217E4FDB00AE95B9 /* Profile */,
);
defaultConfigurationIsVisible = 0;
defaultConfigurationName = Release;
};
/* End XCConfigurationList section */
};
rootObject = 97C146E61CF9000F007C117D /* Project object */;
}

View File

@@ -0,0 +1,101 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1510"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
shouldUseLaunchSchemeArgsEnv = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</MacroExpansion>
<Testables>
<TestableReference
skipped = "NO"
parallelizable = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "331C8080294A63A400263BE5"
BuildableName = "RunnerTests.xctest"
BlueprintName = "RunnerTests"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</TestableReference>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
customLLDBInitFile = "$(SRCROOT)/Flutter/ephemeral/flutter_lldbinit"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
enableGPUValidationMode = "1"
allowLocationSimulation = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</LaunchAction>
<ProfileAction
buildConfiguration = "Profile"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<BuildableProductRunnable
runnableDebuggingMode = "0">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "97C146ED1CF9000F007C117D"
BuildableName = "Runner.app"
BlueprintName = "Runner"
ReferencedContainer = "container:Runner.xcodeproj">
</BuildableReference>
</BuildableProductRunnable>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@@ -0,0 +1,13 @@
import Flutter
import UIKit
@main
@objc class AppDelegate: FlutterAppDelegate {
override func application(
_ application: UIApplication,
didFinishLaunchingWithOptions launchOptions: [UIApplication.LaunchOptionsKey: Any]?
) -> Bool {
GeneratedPluginRegistrant.register(with: self)
return super.application(application, didFinishLaunchingWithOptions: launchOptions)
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 295 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 450 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 282 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 462 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 704 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 406 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 586 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 862 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 762 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.4 KiB

View File

@@ -5,7 +5,7 @@
<key>CFBundleDevelopmentRegion</key>
<string>$(DEVELOPMENT_LANGUAGE)</string>
<key>CFBundleDisplayName</key>
<string>Covas Mobile</string>
<string>Covas Mobile New</string>
<key>CFBundleExecutable</key>
<string>$(EXECUTABLE_NAME)</string>
<key>CFBundleIdentifier</key>
@@ -13,7 +13,7 @@
<key>CFBundleInfoDictionaryVersion</key>
<string>6.0</string>
<key>CFBundleName</key>
<string>covas_mobile</string>
<string>covas_mobile_new</string>
<key>CFBundlePackageType</key>
<string>APPL</string>
<key>CFBundleShortVersionString</key>
@@ -41,9 +41,9 @@
<string>UIInterfaceOrientationLandscapeLeft</string>
<string>UIInterfaceOrientationLandscapeRight</string>
</array>
<key>UIViewControllerBasedStatusBarAppearance</key>
<false/>
<key>CADisableMinimumFrameDurationOnPhone</key>
<true/>
<key>UIApplicationSupportsIndirectInputEvents</key>
<true/>
</dict>
</plist>

View File

@@ -0,0 +1,12 @@
import Flutter
import UIKit
import XCTest
class RunnerTests: XCTestCase {
func testExample() {
// If you add code to the Runner application, consider adding tests here.
// See https://developer.apple.com/documentation/xctest for more information about using XCTest.
}
}

View File

@@ -0,0 +1,5 @@
arb-dir: lib/l10n
template-arb-file: app_en.arb
output-localization-file: app_localizations.dart
output-class: AppLocalizations
output-dir: lib/gen_l10n

View File

@@ -0,0 +1,209 @@
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
import 'dart:io';
import '../pages/EditProfile.dart';
import '../pages/EditSettings.dart';
import '../pages/ListItemMenu.dart';
import 'alert.dart';
import '../variable/globals.dart' as globals;
import '../pages/LoginDemo.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart'; // Import dotenv
import 'package:encrypt_shared_preferences/provider.dart';
import 'package:provider/provider.dart';
import '../locale_provider.dart';
import 'package:covas_mobile/gen_l10n/app_localizations.dart';
class MyDrawer extends StatelessWidget with ShowAlertDialog {
Future<void> logout(BuildContext context) async {
SharedPreferences prefs = await SharedPreferences.getInstance();
var accessToken = prefs.getString("access_token") ?? "";
if (accessToken.isNotEmpty) {
var url = Uri.parse("${globals.api}/token");
try {
var response = await http.delete(url, headers: {
"Content-Type": "application/json",
HttpHeaders.cookieHeader: "access_token=${accessToken}"
});
print("Status code logout ${response.statusCode}");
if (response.statusCode == 200) {
await prefs.remove("access_token");
await dotenv.load(fileName: ".env"); // Load .env file
final keyEncrypt = dotenv.env['KEY_ENCRYPT'] ?? '';
if (keyEncrypt.isNotEmpty) {
await EncryptedSharedPreferences.initialize(keyEncrypt);
var sharedPref = EncryptedSharedPreferences.getInstance();
String username = sharedPref.getString("username") ?? "";
String password = sharedPref.getString("password") ?? "";
if ((username.isEmpty) || (password.isEmpty)) {
sharedPref.remove("username");
sharedPref.remove("password");
}
}
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (_) => LoginDemo()),
(route) => false, // Remove all previous routes
);
} else {
String errorMessage;
switch (response.statusCode) {
case 400:
errorMessage = "Bad Request: Please check your input.";
break;
case 401:
errorMessage = "Unauthorized: Invalid credentials.";
break;
case 403:
errorMessage = "Forbidden: You don't have permission.";
break;
case 404:
errorMessage = "Not Found: The resource was not found.";
break;
case 500:
errorMessage =
"Server Error: Something went wrong on the server.";
break;
default:
errorMessage = "Unexpected Error: ${response.statusCode}";
break;
}
print(errorMessage);
showAlertDialog(context, "Error", errorMessage);
}
} catch (e) {
print("Error: $e");
showAlertDialog(
context, "Error", "An error occurred. Please try again.");
}
} else {
showAlertDialog(context, "Error", "Invalid token.");
}
}
@override
Widget build(BuildContext context) {
final loc = AppLocalizations.of(context);
final localeProvider = Provider.of<LocaleProvider>(context);
return Drawer(
child: ListView(
padding: EdgeInsets.zero,
children: [
// Drawer Header
DrawerHeader(
decoration: BoxDecoration(
color: Colors.blue,
),
child: Text(
'Menu',
style: TextStyle(
color: Colors.white,
fontSize: 24,
),
),
),
// Drawer Items
ListTile(
leading: Icon(Icons.home),
title: Text(loc?.home ?? "Home"),
onTap: () {
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (_) => ListItemMenu()));
/// Close the drawer
},
),
ListTile(
leading: Icon(Icons.settings),
title: Text(loc?.settings ?? 'Settings'),
onTap: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (_) => EditSettings())); // Close the drawer
},
),
ListTile(
leading: Icon(Icons.account_circle),
title: Text(loc?.update_profile ?? 'Update profile'),
onTap: () {
Navigator.pushReplacement(
context,
MaterialPageRoute(
builder: (_) => EditProfile())); // Close the drawer
},
),
ListTile(
leading: Icon(Icons.language),
title: Text(loc?.language ?? 'Language'),
onTap: () {
showDialog(
context: context,
builder: (_) => AlertDialog(
title: Text(loc?.select_language ?? 'Select Language'),
content: Column(
mainAxisSize: MainAxisSize.min,
children: [
ListTile(
leading: Icon(Icons.flag),
title: Text(loc?.french ?? 'Français'),
onTap: () {
Provider.of<LocaleProvider>(context, listen: false)
.setLocale(const Locale('fr'));
Navigator.of(context).pop();
},
),
ListTile(
leading: Icon(Icons.flag_outlined),
title: Text(loc?.english ?? 'English'),
onTap: () {
Provider.of<LocaleProvider>(context, listen: false)
.setLocale(const Locale('en'));
Navigator.of(context).pop();
},
),
ListTile(
leading: Icon(Icons.flag_outlined),
title: Text(loc?.german ?? 'German'),
onTap: () {
Provider.of<LocaleProvider>(context, listen: false)
.setLocale(const Locale('de'));
Navigator.of(context).pop();
},
),
],
),
),
);
},
),
ListTile(
leading: Icon(Icons.info),
title: Text(loc?.about ?? 'About'),
onTap: () {
showAlertDialog(context, loc?.about ?? 'About',
"Version 0.0.1"); // Close the drawer
},
),
ListTile(
leading: Icon(Icons.logout),
title: Text(loc?.log_out ?? 'Log out'),
onTap: () async {
logout(context);
// Close the drawer
},
),
],
),
);
}
}

View File

@@ -0,0 +1,27 @@
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
class AdHelper {
static Future<BannerAd> createBannerAd(Function setStateCallback) async {
await dotenv.load(fileName: ".env");
final adUnitId = dotenv.env['AD_UNIT_ID'] ?? '';
BannerAd bannerAd = BannerAd(
adUnitId: adUnitId,
size: AdSize.banner,
request: AdRequest(),
listener: BannerAdListener(
onAdLoaded: (ad) {
setStateCallback(() {});
},
onAdFailedToLoad: (ad, error) {
print('Banner Ad failed to load: $error');
ad.dispose();
},
),
);
bannerAd.load();
return bannerAd;
}
}

View File

@@ -1,12 +1,10 @@
import 'package:flutter/material.dart';
import '../main.dart';
mixin ShowErrorDialog<T extends StatefulWidget> on State<T> {
void showErrorDialog(BuildContext context, String text) {
mixin ShowAlertDialog {
void showAlertDialog(BuildContext context, String title, String text) {
// Create AlertDialog
AlertDialog dialog = AlertDialog(
title: Text("Error"),
title: Text(title),
content: Text(text),
actions: [
ElevatedButton(

View File

@@ -0,0 +1,141 @@
import 'dart:convert';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
import '../variable/globals.dart' as globals;
import 'dart:io';
import 'package:flutter/material.dart';
import 'package:encrypt_shared_preferences/provider.dart';
import '../pages/LoginDemo.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart'; // Import dotenv
class AuthService {
// Login with username and password
Future<bool> login(String username, String password,
{bool rememberMe = false}) async {
final url = Uri.parse("${globals.api}/token");
try {
final response = await http.post(
url,
headers: {
'accept': 'application/json',
'Content-Type': 'application/x-www-form-urlencoded',
},
body: {"username": username, "password": password},
);
if (response.statusCode == 200 || response.statusCode == 201) {
final prefs = await SharedPreferences.getInstance();
if (rememberMe) {
await dotenv.load(fileName: ".env"); // Load .env file
final keyEncrypt = dotenv.env['KEY_ENCRYPT'] ?? '';
if (keyEncrypt.isNotEmpty) {
await EncryptedSharedPreferences.initialize(keyEncrypt);
var sharedPref = EncryptedSharedPreferences.getInstance();
sharedPref.setString("username", username);
sharedPref.setString("password", password);
}
}
final cookies = response.headers["set-cookie"]?.split(";") ?? [];
for (final cookie in cookies) {
final cookieParts = cookie.split(",");
for (final part in cookieParts) {
final keyValue = part.split("=");
if (keyValue.length == 2 && keyValue[0] == "access_token") {
prefs.setString("access_token", keyValue[1]);
}
}
}
return true;
} else {
return false;
}
} catch (e) {
print("Login error: $e");
return false;
}
}
// Logout
Future<void> logout() async {
final prefs = await SharedPreferences.getInstance();
await prefs.remove("access_token");
}
Future<bool> isLoggedIn() async {
final prefs = await SharedPreferences.getInstance();
final accessToken = prefs.getString("access_token");
if (accessToken == null || accessToken.isEmpty) {
print("No access token found.");
return false;
}
print("Checking token validity...");
var url = Uri.parse("${globals.api}/token");
try {
final response = await http.get(
url,
headers: {
HttpHeaders.cookieHeader: "access_token=$accessToken",
"Content-Type": "application/json",
},
);
if (response.statusCode == 200) {
print("Token is valid.");
return true;
} else {
print("Token is invalid. Status code: ${response.statusCode}");
await dotenv.load(fileName: ".env"); // Load .env file
final keyEncrypt = dotenv.env['KEY_ENCRYPT'] ?? '';
if (keyEncrypt.isNotEmpty) {
await EncryptedSharedPreferences.initialize(keyEncrypt);
var sharedPref = EncryptedSharedPreferences.getInstance();
String username = sharedPref.getString("username") ?? "";
String password = sharedPref.getString("password") ?? "";
if ((username.isEmpty) || (password.isEmpty)) {
sharedPref.remove("username");
sharedPref.remove("password");
await prefs.remove("access_token"); // Clear invalid token
return false;
} else {
return login(username, password);
}
} else {
return false;
}
}
} catch (e) {
print("Error while checking token: $e");
return false;
}
}
Future<void> checkTokenStatus(context) async {
bool loggedIn = await isLoggedIn();
SharedPreferences prefs = await SharedPreferences.getInstance();
if (!loggedIn) {
await prefs.remove("access_token"); // Correctly remove the token
Navigator.pushAndRemoveUntil(
context,
MaterialPageRoute(builder: (_) => LoginDemo()),
(route) => false, // Remove all previous routes
);
}
}
// Get stored access token
Future<String?> getAccessToken() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString("access_token");
}
// Login with Google
}

View File

@@ -0,0 +1,54 @@
class Events {
String? id;
String? name;
String? place;
String? startDate;
String? endDate;
String? description;
String? link;
String? ticket;
double? latitude;
double? longitude;
List<String>? tags;
List<String>? organizers;
String? imgUrl;
int? interestedCount;
bool? interested;
Events(
{this.place,
this.id,
this.name,
this.startDate,
this.description,
this.endDate,
this.tags,
this.latitude,
this.longitude,
this.organizers,
this.link,
this.ticket,
this.imgUrl,
this.interestedCount,
this.interested});
Events.fromJson(Map<String, dynamic> json) {
id = json['id'] as String?;
name = json['name'] as String?;
place = json['place'] as String?;
startDate = json['start_date'] as String?;
endDate = json['end_date'] as String?;
description = json['description'] as String?;
latitude = (json['latitude'] as num?)?.toDouble(); // Safely cast to double
longitude =
(json['longitude'] as num?)?.toDouble(); // Safely cast to double
tags = (json['tags'] as List<dynamic>?)
?.cast<String>(); // Convert List<dynamic> to List<String>
organizers = (json['organizers'] as List<dynamic>?)
?.cast<String>(); // Convert List<dynamic> to List<String>
imgUrl = json['imgUrl'] as String?;
link = json['link'] as String?;
ticket = json['ticket'] as String?;
interested = json['interested'] as bool?;
interestedCount = json['interested_count'] as int?;
}
}

View File

@@ -0,0 +1,89 @@
import 'package:flutter_local_notifications/flutter_local_notifications.dart';
import 'package:timezone/timezone.dart' as tz;
import 'package:timezone/data/latest_all.dart' as tz;
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:covas_mobile/gen_l10n/app_localizations.dart';
import 'package:provider/provider.dart';
class NotificationService {
static final FlutterLocalNotificationsPlugin _notificationsPlugin =
FlutterLocalNotificationsPlugin();
/// Initialisation (à appeler dans main())
static Future<void> initialize() async {
tz.initializeTimeZones();
const AndroidInitializationSettings androidInitSettings =
AndroidInitializationSettings('@mipmap/ic_launcher');
const InitializationSettings initSettings = InitializationSettings(
android: androidInitSettings,
iOS: DarwinInitializationSettings(),
);
await _notificationsPlugin.initialize(initSettings);
// Demande les permissions au lancement
await requestPermissions();
}
/// Demander les permissions (Android 13+ et iOS)
static Future<void> requestPermissions() async {
// Android 13+
final androidImplementation =
_notificationsPlugin.resolvePlatformSpecificImplementation<
AndroidFlutterLocalNotificationsPlugin>();
await androidImplementation?.requestNotificationsPermission();
// iOS
final iosImplementation =
_notificationsPlugin.resolvePlatformSpecificImplementation<
IOSFlutterLocalNotificationsPlugin>();
await iosImplementation?.requestPermissions(
alert: true,
badge: true,
sound: true,
);
}
/// Planifie une notification 1h avant lévènement
static Future<void> scheduleEventNotification({
required String eventId,
required String title,
required String body,
required DateTime eventDate,
}) async {
final scheduledDate = eventDate.subtract(const Duration(hours: 1));
if (scheduledDate.isBefore(DateTime.now())) {
// Trop tard pour notifier
return;
}
await _notificationsPlugin.zonedSchedule(
eventId.hashCode, // identifiant unique pour lévènement
title,
body,
tz.TZDateTime.from(scheduledDate, tz.local),
const NotificationDetails(
android: AndroidNotificationDetails(
'events_channel',
'Events',
channelDescription: 'Favorite event notifications ',
importance: Importance.high,
priority: Priority.high,
),
iOS: DarwinNotificationDetails(),
),
androidScheduleMode: AndroidScheduleMode
.inexactAllowWhileIdle, // évite l'erreur Exact Alarm
matchDateTimeComponents: DateTimeComponents.dateAndTime,
);
}
/// Annule une notification planifiée
static Future<void> cancel(String eventId) async {
await _notificationsPlugin.cancel(eventId.hashCode);
}
}

View File

@@ -0,0 +1,977 @@
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/widgets.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:intl/intl.dart' as intl;
import 'app_localizations_de.dart';
import 'app_localizations_en.dart';
import 'app_localizations_fr.dart';
// ignore_for_file: type=lint
/// Callers can lookup localized strings with an instance of AppLocalizations
/// returned by `AppLocalizations.of(context)`.
///
/// Applications need to include `AppLocalizations.delegate()` in their app's
/// `localizationDelegates` list, and the locales they support in the app's
/// `supportedLocales` list. For example:
///
/// ```dart
/// import 'gen_l10n/app_localizations.dart';
///
/// return MaterialApp(
/// localizationsDelegates: AppLocalizations.localizationsDelegates,
/// supportedLocales: AppLocalizations.supportedLocales,
/// home: MyApplicationHome(),
/// );
/// ```
///
/// ## Update pubspec.yaml
///
/// Please make sure to update your pubspec.yaml to include the following
/// packages:
///
/// ```yaml
/// dependencies:
/// # Internationalization support.
/// flutter_localizations:
/// sdk: flutter
/// intl: any # Use the pinned version from flutter_localizations
///
/// # Rest of dependencies
/// ```
///
/// ## iOS Applications
///
/// iOS applications define key application metadata, including supported
/// locales, in an Info.plist file that is built into the application bundle.
/// To configure the locales supported by your app, youll need to edit this
/// file.
///
/// First, open your projects ios/Runner.xcworkspace Xcode workspace file.
/// Then, in the Project Navigator, open the Info.plist file under the Runner
/// projects Runner folder.
///
/// Next, select the Information Property List item, select Add Item from the
/// Editor menu, then select Localizations from the pop-up menu.
///
/// Select and expand the newly-created Localizations item then, for each
/// locale your application supports, add a new item and select the locale
/// you wish to add from the pop-up menu in the Value field. This list should
/// be consistent with the languages listed in the AppLocalizations.supportedLocales
/// property.
abstract class AppLocalizations {
AppLocalizations(String locale)
: localeName = intl.Intl.canonicalizedLocale(locale.toString());
final String localeName;
static AppLocalizations? of(BuildContext context) {
return Localizations.of<AppLocalizations>(context, AppLocalizations);
}
static const LocalizationsDelegate<AppLocalizations> delegate =
_AppLocalizationsDelegate();
/// A list of this localizations delegate along with the default localizations
/// delegates.
///
/// Returns a list of localizations delegates containing this delegate along with
/// GlobalMaterialLocalizations.delegate, GlobalCupertinoLocalizations.delegate,
/// and GlobalWidgetsLocalizations.delegate.
///
/// Additional delegates can be added by appending to this list in
/// MaterialApp. This list does not have to be used at all if a custom list
/// of delegates is preferred or required.
static const List<LocalizationsDelegate<dynamic>> localizationsDelegates =
<LocalizationsDelegate<dynamic>>[
delegate,
GlobalMaterialLocalizations.delegate,
GlobalCupertinoLocalizations.delegate,
GlobalWidgetsLocalizations.delegate,
];
/// A list of this localizations delegate's supported locales.
static const List<Locale> supportedLocales = <Locale>[
Locale('de'),
Locale('en'),
Locale('fr')
];
/// No description provided for @menu_list.
///
/// In en, this message translates to:
/// **'Event list menu'**
String get menu_list;
/// No description provided for @language.
///
/// In en, this message translates to:
/// **'Language'**
String get language;
/// No description provided for @home.
///
/// In en, this message translates to:
/// **'Home'**
String get home;
/// No description provided for @settings.
///
/// In en, this message translates to:
/// **'Settings'**
String get settings;
/// No description provided for @update_profile.
///
/// In en, this message translates to:
/// **'Update profile'**
String get update_profile;
/// No description provided for @about.
///
/// In en, this message translates to:
/// **'About'**
String get about;
/// No description provided for @log_out.
///
/// In en, this message translates to:
/// **'Log out'**
String get log_out;
/// No description provided for @french.
///
/// In en, this message translates to:
/// **'French'**
String get french;
/// No description provided for @english.
///
/// In en, this message translates to:
/// **'English'**
String get english;
/// No description provided for @german.
///
/// In en, this message translates to:
/// **'German'**
String get german;
/// No description provided for @select_language.
///
/// In en, this message translates to:
/// **'Select language'**
String get select_language;
/// No description provided for @search_item.
///
/// In en, this message translates to:
/// **'Search by item'**
String get search_item;
/// No description provided for @search_tag.
///
/// In en, this message translates to:
/// **'Search by tags'**
String get search_tag;
/// No description provided for @search_geographical.
///
/// In en, this message translates to:
/// **'Search by geographical zone'**
String get search_geographical;
/// No description provided for @show_date_field.
///
/// In en, this message translates to:
/// **'Show Date Fields'**
String get show_date_field;
/// No description provided for @hide_date_field.
///
/// In en, this message translates to:
/// **'Hide Date Fields'**
String get hide_date_field;
/// No description provided for @no_data.
///
/// In en, this message translates to:
/// **'No data available'**
String get no_data;
/// No description provided for @search.
///
/// In en, this message translates to:
/// **'Search'**
String get search;
/// No description provided for @no_events.
///
/// In en, this message translates to:
/// **'No events available for this location.'**
String get no_events;
/// No description provided for @start_date.
///
/// In en, this message translates to:
/// **'Start date'**
String get start_date;
/// No description provided for @end_date.
///
/// In en, this message translates to:
/// **'End date'**
String get end_date;
/// No description provided for @failed_suggestions.
///
/// In en, this message translates to:
/// **'Failed to load suggestions'**
String get failed_suggestions;
/// No description provided for @error.
///
/// In en, this message translates to:
/// **'Error'**
String get error;
/// No description provided for @password_different.
///
/// In en, this message translates to:
/// **'Must write a different password'**
String get password_different;
/// No description provided for @create.
///
/// In en, this message translates to:
/// **'Creation'**
String get create;
/// No description provided for @user_create.
///
/// In en, this message translates to:
/// **'Your user created'**
String get user_create;
/// No description provided for @user_update.
///
/// In en, this message translates to:
/// **'Your user updated'**
String get user_update;
/// No description provided for @request_error.
///
/// In en, this message translates to:
/// **'Poorly constructed query'**
String get request_error;
/// No description provided for @incorrect_password.
///
/// In en, this message translates to:
/// **'Incorrect password'**
String get incorrect_password;
/// No description provided for @unknown_user.
///
/// In en, this message translates to:
/// **'Unknown user'**
String get unknown_user;
/// No description provided for @disabled_user.
///
/// In en, this message translates to:
/// **'User disabled'**
String get disabled_user;
/// No description provided for @invalid_token.
///
/// In en, this message translates to:
/// **'Invalid token'**
String get invalid_token;
/// No description provided for @internal_error_server.
///
/// In en, this message translates to:
/// **'Internal error server'**
String get internal_error_server;
/// No description provided for @unknown_error_auth.
///
/// In en, this message translates to:
/// **'Unknown error authentification'**
String get unknown_error_auth;
/// No description provided for @required_input.
///
/// In en, this message translates to:
/// **'Required input'**
String get required_input;
/// No description provided for @create_profile.
///
/// In en, this message translates to:
/// **'Create profile'**
String get create_profile;
/// No description provided for @edit_pseudo.
///
/// In en, this message translates to:
/// **'Edit pseudo'**
String get edit_pseudo;
/// No description provided for @password.
///
/// In en, this message translates to:
/// **'Password'**
String get password;
/// No description provided for @enter_password.
///
/// In en, this message translates to:
/// **'Enter the passord'**
String get enter_password;
/// No description provided for @password_confirmed.
///
/// In en, this message translates to:
/// **'Password confirmed'**
String get password_confirmed;
/// No description provided for @last_name.
///
/// In en, this message translates to:
/// **'Last name'**
String get last_name;
/// No description provided for @first_name.
///
/// In en, this message translates to:
/// **'First name'**
String get first_name;
/// No description provided for @email.
///
/// In en, this message translates to:
/// **'Mail'**
String get email;
/// No description provided for @edit_last_name.
///
/// In en, this message translates to:
/// **'Edit name'**
String get edit_last_name;
/// No description provided for @edit_first_name.
///
/// In en, this message translates to:
/// **'Edit first name'**
String get edit_first_name;
/// No description provided for @edit_email.
///
/// In en, this message translates to:
/// **'Edit email address'**
String get edit_email;
/// No description provided for @birth_date.
///
/// In en, this message translates to:
/// **'Birth date'**
String get birth_date;
/// No description provided for @edit_birth.
///
/// In en, this message translates to:
/// **'Edit birth date'**
String get edit_birth;
/// No description provided for @create_profile_button.
///
/// In en, this message translates to:
/// **'Create profile'**
String get create_profile_button;
/// No description provided for @take_picture.
///
/// In en, this message translates to:
/// **'Take a picture'**
String get take_picture;
/// No description provided for @error_ia.
///
/// In en, this message translates to:
/// **'Google AI failed to analyze picture. Retry with another one'**
String get error_ia;
/// No description provided for @no_data_geo.
///
/// In en, this message translates to:
/// **'No geographical data'**
String get no_data_geo;
/// No description provided for @response_status_update.
///
/// In en, this message translates to:
/// **'response status code update'**
String get response_status_update;
/// No description provided for @error_token.
///
/// In en, this message translates to:
/// **'Token error'**
String get error_token;
/// No description provided for @error_format.
///
/// In en, this message translates to:
/// **'Data format error given by AI'**
String get error_format;
/// No description provided for @display_picture.
///
/// In en, this message translates to:
/// **'Display the Picture'**
String get display_picture;
/// No description provided for @analyze_image.
///
/// In en, this message translates to:
/// **'Image Analyze in progress'**
String get analyze_image;
/// No description provided for @loading_progress.
///
/// In en, this message translates to:
/// **'Loading progress'**
String get loading_progress;
/// No description provided for @error_event.
///
/// In en, this message translates to:
/// **'Event error'**
String get error_event;
/// No description provided for @no_future_event.
///
/// In en, this message translates to:
/// **'No future event'**
String get no_future_event;
/// No description provided for @error_user.
///
/// In en, this message translates to:
/// **'Error user'**
String get error_user;
/// No description provided for @empty_input.
///
/// In en, this message translates to:
/// **'Empty input'**
String get empty_input;
/// No description provided for @info_event.
///
/// In en, this message translates to:
/// **'Event info'**
String get info_event;
/// No description provided for @event_already.
///
/// In en, this message translates to:
/// **'Event already exists'**
String get event_already;
/// No description provided for @picture_error.
///
/// In en, this message translates to:
/// **'Picture error'**
String get picture_error;
/// No description provided for @no_picture_published.
///
/// In en, this message translates to:
/// **'No picture published'**
String get no_picture_published;
/// No description provided for @event_update.
///
/// In en, this message translates to:
/// **'Event updated'**
String get event_update;
/// No description provided for @location.
///
/// In en, this message translates to:
/// **'Location'**
String get location;
/// No description provided for @add_event.
///
/// In en, this message translates to:
/// **'Add or Update a event'**
String get add_event;
/// No description provided for @edit_image.
///
/// In en, this message translates to:
/// **'Edit pictures'**
String get edit_image;
/// No description provided for @name.
///
/// In en, this message translates to:
/// **'Name'**
String get name;
/// No description provided for @edit_event_name.
///
/// In en, this message translates to:
/// **'Edit event name'**
String get edit_event_name;
/// No description provided for @start_time.
///
/// In en, this message translates to:
/// **'Start time'**
String get start_time;
/// No description provided for @end_time.
///
/// In en, this message translates to:
/// **'End time'**
String get end_time;
/// No description provided for @select_date.
///
/// In en, this message translates to:
/// **'Click to select a date'**
String get select_date;
/// No description provided for @select_time.
///
/// In en, this message translates to:
/// **'Click to select a time'**
String get select_time;
/// No description provided for @tag.
///
/// In en, this message translates to:
/// **'Tags'**
String get tag;
/// No description provided for @already_tag.
///
/// In en, this message translates to:
/// **'You have already this tags'**
String get already_tag;
/// No description provided for @enter_tag.
///
/// In en, this message translates to:
/// **'Enter a tag'**
String get enter_tag;
/// No description provided for @organizer.
///
/// In en, this message translates to:
/// **'Organizer'**
String get organizer;
/// No description provided for @already_organiser.
///
/// In en, this message translates to:
/// **'You have already a organizer'**
String get already_organiser;
/// No description provided for @enter_organizer.
///
/// In en, this message translates to:
/// **'Enter a organizer'**
String get enter_organizer;
/// No description provided for @description.
///
/// In en, this message translates to:
/// **'Description'**
String get description;
/// No description provided for @describe_event.
///
/// In en, this message translates to:
/// **'Describe event'**
String get describe_event;
/// No description provided for @add.
///
/// In en, this message translates to:
/// **'Add'**
String get add;
/// No description provided for @different_password_error.
///
/// In en, this message translates to:
/// **'Different password'**
String get different_password_error;
/// No description provided for @update.
///
/// In en, this message translates to:
/// **'Update'**
String get update;
/// No description provided for @updated.
///
/// In en, this message translates to:
/// **'Updated'**
String get updated;
/// No description provided for @settings_updated.
///
/// In en, this message translates to:
/// **'Settings updated'**
String get settings_updated;
/// No description provided for @define_kilometer.
///
/// In en, this message translates to:
/// **'Define Kilometer'**
String get define_kilometer;
/// No description provided for @email_sent.
///
/// In en, this message translates to:
/// **'Email has been sent'**
String get email_sent;
/// No description provided for @forgot_password.
///
/// In en, this message translates to:
/// **'Forgot password'**
String get forgot_password;
/// No description provided for @enter_email.
///
/// In en, this message translates to:
/// **'Enter the email'**
String get enter_email;
/// No description provided for @send_email.
///
/// In en, this message translates to:
/// **'Send email'**
String get send_email;
/// No description provided for @invalid_cache.
///
/// In en, this message translates to:
/// **'Invalid cache'**
String get invalid_cache;
/// No description provided for @item_date.
///
/// In en, this message translates to:
/// **'Date : '**
String get item_date;
/// No description provided for @item_maps.
///
/// In en, this message translates to:
/// **'Maps : '**
String get item_maps;
/// No description provided for @item_organizer.
///
/// In en, this message translates to:
/// **'Organizer : '**
String get item_organizer;
/// No description provided for @item_description.
///
/// In en, this message translates to:
/// **'Description : '**
String get item_description;
/// No description provided for @item_tags.
///
/// In en, this message translates to:
/// **'Tags : '**
String get item_tags;
/// No description provided for @failed_auth.
///
/// In en, this message translates to:
/// **'Authentification failed'**
String get failed_auth;
/// No description provided for @login_page.
///
/// In en, this message translates to:
/// **'Login page'**
String get login_page;
/// No description provided for @pseudo.
///
/// In en, this message translates to:
/// **'Pseudo'**
String get pseudo;
/// No description provided for @enter_existing_pseudo.
///
/// In en, this message translates to:
/// **'Enter a existing pseudo'**
String get enter_existing_pseudo;
/// No description provided for @remembr_me.
///
/// In en, this message translates to:
/// **'Remember me'**
String get remembr_me;
/// No description provided for @new_user.
///
/// In en, this message translates to:
/// **'New User? Create Account'**
String get new_user;
/// No description provided for @sign_in.
///
/// In en, this message translates to:
/// **'Sign in'**
String get sign_in;
/// No description provided for @map_token.
///
/// In en, this message translates to:
/// **'Mapbox Access Token is not available'**
String get map_token;
/// No description provided for @geo_disabled.
///
/// In en, this message translates to:
/// **'Location services are disabled.'**
String get geo_disabled;
/// No description provided for @permission_denied.
///
/// In en, this message translates to:
/// **'Location permissions are denied.'**
String get permission_denied;
/// No description provided for @enable_permission.
///
/// In en, this message translates to:
/// **'Location permissions are permanently denied. Enable them in settings.'**
String get enable_permission;
/// No description provided for @no_last_position.
///
/// In en, this message translates to:
/// **'No last known position available.'**
String get no_last_position;
/// No description provided for @failed_location.
///
/// In en, this message translates to:
/// **'Failed to get user location'**
String get failed_location;
/// No description provided for @failed_fetch.
///
/// In en, this message translates to:
/// **'Failed to fetch the route'**
String get failed_fetch;
/// No description provided for @invalid_coordinates_symbol.
///
/// In en, this message translates to:
/// **'Invalid coordinates, cannot add symbol.'**
String get invalid_coordinates_symbol;
/// No description provided for @error_symbol.
///
/// In en, this message translates to:
/// **'Error when adding symbol.'**
String get error_symbol;
/// No description provided for @position_not_init.
///
/// In en, this message translates to:
/// **'User position is not yet initialized. Try again.'**
String get position_not_init;
/// No description provided for @invalid_coordinates.
///
/// In en, this message translates to:
/// **'Invalid coordinates.'**
String get invalid_coordinates;
/// No description provided for @walking.
///
/// In en, this message translates to:
/// **'Walking'**
String get walking;
/// No description provided for @cycling.
///
/// In en, this message translates to:
/// **'Cycling'**
String get cycling;
/// No description provided for @driving.
///
/// In en, this message translates to:
/// **'Driving'**
String get driving;
/// No description provided for @get_direction.
///
/// In en, this message translates to:
/// **'Get Directions and Markers'**
String get get_direction;
/// No description provided for @missing_token.
///
/// In en, this message translates to:
/// **'Missing access token'**
String get missing_token;
/// No description provided for @geocoding_error.
///
/// In en, this message translates to:
/// **'Error when geocoding'**
String get geocoding_error;
/// No description provided for @no_found_place.
///
/// In en, this message translates to:
/// **'No found place'**
String get no_found_place;
/// No description provided for @upload_error.
///
/// In en, this message translates to:
/// **'Error when image uploading'**
String get upload_error;
/// No description provided for @event_added.
///
/// In en, this message translates to:
/// **'Event added'**
String get event_added;
/// No description provided for @unknown_error.
///
/// In en, this message translates to:
/// **'Unknown error'**
String get unknown_error;
/// No description provided for @app_error.
///
/// In en, this message translates to:
/// **'Application error'**
String get app_error;
/// No description provided for @at.
///
/// In en, this message translates to:
/// **'at'**
String get at;
/// No description provided for @to_date.
///
/// In en, this message translates to:
/// **'to'**
String get to_date;
/// No description provided for @item_link.
///
/// In en, this message translates to:
/// **'Link : '**
String get item_link;
/// No description provided for @item_ticket.
///
/// In en, this message translates to:
/// **'Ticket : '**
String get item_ticket;
/// No description provided for @link.
///
/// In en, this message translates to:
/// **'Link'**
String get link;
/// No description provided for @edit_link.
///
/// In en, this message translates to:
/// **'Edit link name'**
String get edit_link;
/// No description provided for @ticket.
///
/// In en, this message translates to:
/// **'Ticket'**
String get ticket;
/// No description provided for @edit_ticket.
///
/// In en, this message translates to:
/// **'Edit ticket link'**
String get edit_ticket;
/// No description provided for @toogle_interest.
///
/// In en, this message translates to:
/// **'Error toggle interest'**
String get toogle_interest;
/// No description provided for @error_update.
///
/// In en, this message translates to:
/// **'Error when updating'**
String get error_update;
/// No description provided for @count_interested.
///
/// In en, this message translates to:
/// **'Interested people number'**
String get count_interested;
}
class _AppLocalizationsDelegate
extends LocalizationsDelegate<AppLocalizations> {
const _AppLocalizationsDelegate();
@override
Future<AppLocalizations> load(Locale locale) {
return SynchronousFuture<AppLocalizations>(lookupAppLocalizations(locale));
}
@override
bool isSupported(Locale locale) =>
<String>['de', 'en', 'fr'].contains(locale.languageCode);
@override
bool shouldReload(_AppLocalizationsDelegate old) => false;
}
AppLocalizations lookupAppLocalizations(Locale locale) {
// Lookup logic when only language code is specified.
switch (locale.languageCode) {
case 'de':
return AppLocalizationsDe();
case 'en':
return AppLocalizationsEn();
case 'fr':
return AppLocalizationsFr();
}
throw FlutterError(
'AppLocalizations.delegate failed to load unsupported locale "$locale". This is likely '
'an issue with the localizations generation tool. Please file an issue '
'on GitHub with a reproducible sample app and the gen-l10n configuration '
'that was used.');
}

View File

@@ -0,0 +1,434 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for German (`de`).
class AppLocalizationsDe extends AppLocalizations {
AppLocalizationsDe([String locale = 'de']) : super(locale);
@override
String get menu_list => 'Veranstaltungsmenü';
@override
String get language => 'Sprache';
@override
String get home => 'Startseite';
@override
String get settings => 'Einstellungen';
@override
String get update_profile => 'Profil aktualisieren';
@override
String get about => 'Über';
@override
String get log_out => 'Abmelden';
@override
String get french => 'Französisch';
@override
String get english => 'Englisch';
@override
String get german => 'Deutsch';
@override
String get select_language => 'Sprache auswählen';
@override
String get search_item => 'Nach Element suchen';
@override
String get search_tag => 'Nach Schlagwörtern suchen';
@override
String get search_geographical => 'Nach geografischer Zone suchen';
@override
String get show_date_field => 'Datumsfelder anzeigen';
@override
String get hide_date_field => 'Datumsfelder ausblenden';
@override
String get no_data => 'Keine Daten verfügbar';
@override
String get search => 'Suchen';
@override
String get no_events => 'Keine Veranstaltungen für diesen Ort verfügbar.';
@override
String get start_date => 'Anfangsdatum';
@override
String get end_date => 'Enddatum';
@override
String get failed_suggestions => 'Vorschläge konnten nicht geladen werden';
@override
String get error => 'Fehler';
@override
String get password_different => 'Ein anderes Passwort eingeben';
@override
String get create => 'Erstellung';
@override
String get user_create => 'Benutzer wurde erstellt';
@override
String get user_update => 'Benutzer wurde aktualisiert';
@override
String get request_error => 'Fehlerhafte Anfrage';
@override
String get incorrect_password => 'Falsches Passwort';
@override
String get unknown_user => 'Unbekannter Benutzer';
@override
String get disabled_user => 'Benutzer deaktiviert';
@override
String get invalid_token => 'Ungültiger Token';
@override
String get internal_error_server => 'Interner Serverfehler';
@override
String get unknown_error_auth => 'Unbekannter Authentifizierungsfehler';
@override
String get required_input => 'Pflichtfeld';
@override
String get create_profile => 'Profil erstellen';
@override
String get edit_pseudo => 'Benutzernamen bearbeiten';
@override
String get password => 'Passwort';
@override
String get enter_password => 'Passwort eingeben';
@override
String get password_confirmed => 'Passwort bestätigt';
@override
String get last_name => 'Nachname';
@override
String get first_name => 'Vorname';
@override
String get email => 'E-Mail';
@override
String get edit_last_name => 'Nachnamen bearbeiten';
@override
String get edit_first_name => 'Vornamen bearbeiten';
@override
String get edit_email => 'E-Mail-Adresse bearbeiten';
@override
String get birth_date => 'Geburtsdatum';
@override
String get edit_birth => 'Geburtsdatum bearbeiten';
@override
String get create_profile_button => 'Profil erstellen';
@override
String get take_picture => 'Foto aufnehmen';
@override
String get error_ia =>
'Google KI konnte das Bild nicht analysieren. Bitte ein anderes versuchen.';
@override
String get no_data_geo => 'Keine geografischen Daten';
@override
String get response_status_update => 'Statuscode-Antwort aktualisieren';
@override
String get error_token => 'Token-Fehler';
@override
String get error_format => 'Vom KI geliefertes Datenformat ist fehlerhaft';
@override
String get display_picture => 'Bild anzeigen';
@override
String get analyze_image => 'Bildanalyse läuft';
@override
String get loading_progress => 'Ladefortschritt';
@override
String get error_event => 'Veranstaltungsfehler';
@override
String get no_future_event => 'Keine zukünftigen Veranstaltungen';
@override
String get error_user => 'Benutzerfehler';
@override
String get empty_input => 'Eingabefeld leer';
@override
String get info_event => 'Veranstaltungsinfo';
@override
String get event_already => 'Veranstaltung existiert bereits';
@override
String get picture_error => 'Bildfehler';
@override
String get no_picture_published => 'Kein Bild veröffentlicht';
@override
String get event_update => 'Veranstaltung aktualisiert';
@override
String get location => 'Ort';
@override
String get add_event => 'Veranstaltung hinzufügen oder aktualisieren';
@override
String get edit_image => 'Bilder bearbeiten';
@override
String get name => 'Name';
@override
String get edit_event_name => 'Veranstaltungsname bearbeiten';
@override
String get start_time => 'Startzeit';
@override
String get end_time => 'Endzeit';
@override
String get select_date => 'Zum Auswählen eines Datums klicken';
@override
String get select_time => 'Zum Auswählen einer Uhrzeit klicken';
@override
String get tag => 'Schlagwörter';
@override
String get already_tag => 'Dieses Schlagwort ist bereits vorhanden';
@override
String get enter_tag => 'Ein Schlagwort eingeben';
@override
String get organizer => 'Veranstalter';
@override
String get already_organiser => 'Veranstalter bereits vorhanden';
@override
String get enter_organizer => 'Veranstalter eingeben';
@override
String get description => 'Beschreibung';
@override
String get describe_event => 'Veranstaltung beschreiben';
@override
String get add => 'Hinzufügen';
@override
String get different_password_error => 'Passwörter stimmen nicht überein';
@override
String get update => 'Aktualisieren';
@override
String get updated => 'Aktualisiert';
@override
String get settings_updated => 'Einstellungen aktualisiert';
@override
String get define_kilometer => 'Kilometer definieren';
@override
String get email_sent => 'E-Mail wurde gesendet';
@override
String get forgot_password => 'Passwort vergessen';
@override
String get enter_email => 'E-Mail eingeben';
@override
String get send_email => 'E-Mail senden';
@override
String get invalid_cache => 'Ungültiger Cache';
@override
String get item_date => 'Datum : ';
@override
String get item_maps => 'Karte : ';
@override
String get item_organizer => 'Veranstalter : ';
@override
String get item_description => 'Beschreibung : ';
@override
String get item_tags => 'Schlagwörter : ';
@override
String get failed_auth => 'Authentifizierung fehlgeschlagen';
@override
String get login_page => 'Anmeldeseite';
@override
String get pseudo => 'Benutzername';
@override
String get enter_existing_pseudo => 'Vorhandenen Benutzernamen eingeben';
@override
String get remembr_me => 'Angemeldet bleiben';
@override
String get new_user => 'Neuer Benutzer? Konto erstellen';
@override
String get sign_in => 'Anmelden';
@override
String get map_token => 'Mapbox-Zugangstoken ist nicht verfügbar';
@override
String get geo_disabled => 'Standortdienste sind deaktiviert.';
@override
String get permission_denied => 'Standortberechtigungen wurden verweigert.';
@override
String get enable_permission =>
'Standortberechtigungen dauerhaft verweigert. Bitte in den Einstellungen aktivieren.';
@override
String get no_last_position => 'Keine letzte bekannte Position verfügbar.';
@override
String get failed_location => 'Standort konnte nicht ermittelt werden';
@override
String get failed_fetch => 'Route konnte nicht abgerufen werden';
@override
String get invalid_coordinates_symbol =>
'Ungültige Koordinaten, Symbol kann nicht hinzugefügt werden.';
@override
String get error_symbol => 'Fehler beim Hinzufügen des Symbols.';
@override
String get position_not_init =>
'Benutzerposition noch nicht initialisiert. Erneut versuchen.';
@override
String get invalid_coordinates => 'Ungültige Koordinaten.';
@override
String get walking => 'Zu Fuß';
@override
String get cycling => 'Mit dem Fahrrad';
@override
String get driving => 'Mit dem Auto';
@override
String get get_direction => 'Wegbeschreibung und Markierungen anzeigen';
@override
String get missing_token => 'Zugangstoken fehlt';
@override
String get geocoding_error => 'Fehler bei der Geokodierung';
@override
String get no_found_place => 'Kein Ort gefunden';
@override
String get upload_error => 'Fehler beim Hochladen des Bildes';
@override
String get event_added => 'Veranstaltung hinzugefügt';
@override
String get unknown_error => 'Unbekannter Fehler';
@override
String get app_error => 'Anwendungsfehler';
@override
String get at => 'um';
@override
String get to_date => 'bis';
@override
String get item_link => 'Link : ';
@override
String get item_ticket => 'Abendkarte : ';
@override
String get link => 'Link';
@override
String get edit_link => 'Linkereignis bearbeiten';
@override
String get ticket => 'Abendkarte';
@override
String get edit_ticket => 'Ticketlink bearbeiten';
@override
String get toogle_interest => 'Fehler beim Umschalten des Interesses';
@override
String get error_update => 'Fehler beim Update';
@override
String get count_interested => 'Anzahl der Interessenten';
}

View File

@@ -0,0 +1,434 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for English (`en`).
class AppLocalizationsEn extends AppLocalizations {
AppLocalizationsEn([String locale = 'en']) : super(locale);
@override
String get menu_list => 'Event list menu';
@override
String get language => 'Language';
@override
String get home => 'Home';
@override
String get settings => 'Settings';
@override
String get update_profile => 'Update profile';
@override
String get about => 'About';
@override
String get log_out => 'Log out';
@override
String get french => 'French';
@override
String get english => 'English';
@override
String get german => 'German';
@override
String get select_language => 'Select language';
@override
String get search_item => 'Search by item';
@override
String get search_tag => 'Search by tags';
@override
String get search_geographical => 'Search by geographical zone';
@override
String get show_date_field => 'Show Date Fields';
@override
String get hide_date_field => 'Hide Date Fields';
@override
String get no_data => 'No data available';
@override
String get search => 'Search';
@override
String get no_events => 'No events available for this location.';
@override
String get start_date => 'Start date';
@override
String get end_date => 'End date';
@override
String get failed_suggestions => 'Failed to load suggestions';
@override
String get error => 'Error';
@override
String get password_different => 'Must write a different password';
@override
String get create => 'Creation';
@override
String get user_create => 'Your user created';
@override
String get user_update => 'Your user updated';
@override
String get request_error => 'Poorly constructed query';
@override
String get incorrect_password => 'Incorrect password';
@override
String get unknown_user => 'Unknown user';
@override
String get disabled_user => 'User disabled';
@override
String get invalid_token => 'Invalid token';
@override
String get internal_error_server => 'Internal error server';
@override
String get unknown_error_auth => 'Unknown error authentification';
@override
String get required_input => 'Required input';
@override
String get create_profile => 'Create profile';
@override
String get edit_pseudo => 'Edit pseudo';
@override
String get password => 'Password';
@override
String get enter_password => 'Enter the passord';
@override
String get password_confirmed => 'Password confirmed';
@override
String get last_name => 'Last name';
@override
String get first_name => 'First name';
@override
String get email => 'Mail';
@override
String get edit_last_name => 'Edit name';
@override
String get edit_first_name => 'Edit first name';
@override
String get edit_email => 'Edit email address';
@override
String get birth_date => 'Birth date';
@override
String get edit_birth => 'Edit birth date';
@override
String get create_profile_button => 'Create profile';
@override
String get take_picture => 'Take a picture';
@override
String get error_ia =>
'Google AI failed to analyze picture. Retry with another one';
@override
String get no_data_geo => 'No geographical data';
@override
String get response_status_update => 'response status code update';
@override
String get error_token => 'Token error';
@override
String get error_format => 'Data format error given by AI';
@override
String get display_picture => 'Display the Picture';
@override
String get analyze_image => 'Image Analyze in progress';
@override
String get loading_progress => 'Loading progress';
@override
String get error_event => 'Event error';
@override
String get no_future_event => 'No future event';
@override
String get error_user => 'Error user';
@override
String get empty_input => 'Empty input';
@override
String get info_event => 'Event info';
@override
String get event_already => 'Event already exists';
@override
String get picture_error => 'Picture error';
@override
String get no_picture_published => 'No picture published';
@override
String get event_update => 'Event updated';
@override
String get location => 'Location';
@override
String get add_event => 'Add or Update a event';
@override
String get edit_image => 'Edit pictures';
@override
String get name => 'Name';
@override
String get edit_event_name => 'Edit event name';
@override
String get start_time => 'Start time';
@override
String get end_time => 'End time';
@override
String get select_date => 'Click to select a date';
@override
String get select_time => 'Click to select a time';
@override
String get tag => 'Tags';
@override
String get already_tag => 'You have already this tags';
@override
String get enter_tag => 'Enter a tag';
@override
String get organizer => 'Organizer';
@override
String get already_organiser => 'You have already a organizer';
@override
String get enter_organizer => 'Enter a organizer';
@override
String get description => 'Description';
@override
String get describe_event => 'Describe event';
@override
String get add => 'Add';
@override
String get different_password_error => 'Different password';
@override
String get update => 'Update';
@override
String get updated => 'Updated';
@override
String get settings_updated => 'Settings updated';
@override
String get define_kilometer => 'Define Kilometer';
@override
String get email_sent => 'Email has been sent';
@override
String get forgot_password => 'Forgot password';
@override
String get enter_email => 'Enter the email';
@override
String get send_email => 'Send email';
@override
String get invalid_cache => 'Invalid cache';
@override
String get item_date => 'Date : ';
@override
String get item_maps => 'Maps : ';
@override
String get item_organizer => 'Organizer : ';
@override
String get item_description => 'Description : ';
@override
String get item_tags => 'Tags : ';
@override
String get failed_auth => 'Authentification failed';
@override
String get login_page => 'Login page';
@override
String get pseudo => 'Pseudo';
@override
String get enter_existing_pseudo => 'Enter a existing pseudo';
@override
String get remembr_me => 'Remember me';
@override
String get new_user => 'New User? Create Account';
@override
String get sign_in => 'Sign in';
@override
String get map_token => 'Mapbox Access Token is not available';
@override
String get geo_disabled => 'Location services are disabled.';
@override
String get permission_denied => 'Location permissions are denied.';
@override
String get enable_permission =>
'Location permissions are permanently denied. Enable them in settings.';
@override
String get no_last_position => 'No last known position available.';
@override
String get failed_location => 'Failed to get user location';
@override
String get failed_fetch => 'Failed to fetch the route';
@override
String get invalid_coordinates_symbol =>
'Invalid coordinates, cannot add symbol.';
@override
String get error_symbol => 'Error when adding symbol.';
@override
String get position_not_init =>
'User position is not yet initialized. Try again.';
@override
String get invalid_coordinates => 'Invalid coordinates.';
@override
String get walking => 'Walking';
@override
String get cycling => 'Cycling';
@override
String get driving => 'Driving';
@override
String get get_direction => 'Get Directions and Markers';
@override
String get missing_token => 'Missing access token';
@override
String get geocoding_error => 'Error when geocoding';
@override
String get no_found_place => 'No found place';
@override
String get upload_error => 'Error when image uploading';
@override
String get event_added => 'Event added';
@override
String get unknown_error => 'Unknown error';
@override
String get app_error => 'Application error';
@override
String get at => 'at';
@override
String get to_date => 'to';
@override
String get item_link => 'Link : ';
@override
String get item_ticket => 'Ticket : ';
@override
String get link => 'Link';
@override
String get edit_link => 'Edit link name';
@override
String get ticket => 'Ticket';
@override
String get edit_ticket => 'Edit ticket link';
@override
String get toogle_interest => 'Error toggle interest';
@override
String get error_update => 'Error when updating';
@override
String get count_interested => 'Interested people number';
}

View File

@@ -0,0 +1,437 @@
// ignore: unused_import
import 'package:intl/intl.dart' as intl;
import 'app_localizations.dart';
// ignore_for_file: type=lint
/// The translations for French (`fr`).
class AppLocalizationsFr extends AppLocalizations {
AppLocalizationsFr([String locale = 'fr']) : super(locale);
@override
String get menu_list => 'Liste d\'évènement';
@override
String get language => 'Langue';
@override
String get home => 'Accueil';
@override
String get settings => 'Paramètres';
@override
String get update_profile => 'Modifier le profil';
@override
String get about => 'À propos';
@override
String get log_out => 'Se déconnecter';
@override
String get french => 'Français';
@override
String get english => 'Anglais';
@override
String get german => 'Allemand';
@override
String get select_language => 'Selectionne la langue';
@override
String get search_item => 'Recherche par item';
@override
String get search_tag => 'Recherche par tags';
@override
String get search_geographical => 'Recherche par zone géographique';
@override
String get show_date_field => 'Afficher champ date';
@override
String get hide_date_field => 'Cacher Date Fields';
@override
String get no_data => 'Aucune donnée disponible';
@override
String get search => 'Recherche';
@override
String get no_events => 'Pas d\'évènements dans cette localisation';
@override
String get start_date => 'Date de début';
@override
String get end_date => 'Date de fin';
@override
String get failed_suggestions => 'Echec de chargement des suggestions';
@override
String get error => 'Erreur';
@override
String get password_different => 'Tu dois écrire un mot de passe different';
@override
String get create => 'Création';
@override
String get user_create => 'Votre utilisateur a été créé';
@override
String get user_update => 'Votre utilisateur a été modifié';
@override
String get request_error => 'Requête mal construite';
@override
String get incorrect_password => 'Mot de passe incorrect';
@override
String get unknown_user => 'Utilisateur inconnu';
@override
String get disabled_user => 'Utilisateur désactivé';
@override
String get invalid_token => 'Token invalide';
@override
String get internal_error_server => 'Erreur interne de serveur';
@override
String get unknown_error_auth => 'Problème d\'authentification inconnu';
@override
String get required_input => 'Champ requis';
@override
String get create_profile => 'Creation profil';
@override
String get edit_pseudo => 'Modifier le pseudo';
@override
String get password => 'Mot de passe';
@override
String get enter_password => 'Entrez le password';
@override
String get password_confirmed => 'Confirmez le mot de passe';
@override
String get last_name => 'Nom';
@override
String get first_name => 'Prénom';
@override
String get email => 'Email';
@override
String get edit_last_name => 'Modifier le nom';
@override
String get edit_first_name => 'Modifier le prénom';
@override
String get edit_email => 'Modifier l\'email';
@override
String get birth_date => 'Date de naissance';
@override
String get edit_birth => 'Modifier la date de naissance';
@override
String get create_profile_button => 'Créer le profil';
@override
String get take_picture => 'Take a picture';
@override
String get error_ia =>
'L\'IA de Google n\'a pas su analyser l\'image. Recommencer avec une autre';
@override
String get no_data_geo => 'Aucune donnée géographique';
@override
String get response_status_update =>
'Code du statut de réponse de la modification';
@override
String get error_token => 'Erreur de token';
@override
String get error_format => 'Erreur de format de donnée fourni par l\'IA';
@override
String get display_picture => 'Display the Picture';
@override
String get analyze_image => 'Analyse de l\'image en cours';
@override
String get loading_progress => 'Chargement en cours';
@override
String get error_event => 'Erreur de l\'évènement';
@override
String get no_future_event => 'Évènement non futur';
@override
String get error_user => 'Erreur de l\'utilisateur';
@override
String get empty_input => 'Champ vide';
@override
String get info_event => 'Event info';
@override
String get event_already => 'Event already exists';
@override
String get picture_error => 'Erreur image';
@override
String get no_picture_published => 'Image non publiée';
@override
String get event_update => 'Évènement modifié';
@override
String get location => 'Lieu';
@override
String get add_event => 'Ajouter ou modifier un évènement';
@override
String get edit_image => 'Changer la photo';
@override
String get name => 'Nom';
@override
String get edit_event_name => 'Changer le nom de l\'évènement';
@override
String get start_time => 'Heure de début';
@override
String get end_time => 'Heure de fin';
@override
String get select_date => 'Cliquer pour selectionner une date';
@override
String get select_time => 'Cliquer pour selectionner une heure';
@override
String get tag => 'Tags';
@override
String get already_tag => 'Tu as déjà entré ce tag';
@override
String get enter_tag => 'Entrer un tag';
@override
String get organizer => 'Organisateur';
@override
String get already_organiser => 'Tu as déjà rentré cet organisateur';
@override
String get enter_organizer => 'Entrer un organisateur';
@override
String get description => 'Description';
@override
String get describe_event => 'Décrire l\'évènement';
@override
String get add => 'Ajouter';
@override
String get different_password_error => 'Mot de passe différent';
@override
String get update => 'Mettre à jour';
@override
String get updated => 'Mis à jour';
@override
String get settings_updated => 'Paramètre mis à jour';
@override
String get define_kilometer => 'Definir un kilomètre';
@override
String get email_sent => 'Email a été envoyé';
@override
String get forgot_password => 'Mot de passe oublié';
@override
String get enter_email => 'Entrez l\'email';
@override
String get send_email => 'Send email';
@override
String get invalid_cache => 'Cache invalide';
@override
String get item_date => 'Date : ';
@override
String get item_maps => 'Carte : ';
@override
String get item_organizer => 'Organisateurs : ';
@override
String get item_description => 'Description : ';
@override
String get item_tags => 'Tags : ';
@override
String get failed_auth => 'Échec de l\'authenticaton';
@override
String get login_page => 'Page d\'authentification';
@override
String get pseudo => 'Pseudo';
@override
String get enter_existing_pseudo => 'Entrez un pseudo existant';
@override
String get remembr_me => 'Se souvenir de moi';
@override
String get new_user => 'Nouvel utilisateur ? Créer un compte';
@override
String get sign_in => 'Se connecter';
@override
String get map_token => 'Token d\'accès de Mapbox n\'est pas disponible';
@override
String get geo_disabled => 'Les services de localisation sont désactivés.';
@override
String get permission_denied =>
'Les permissions de localisation sont refusées.';
@override
String get enable_permission =>
'Les permissions de localisation sont toujours désactivés. Il faut les désactiver';
@override
String get no_last_position => 'Aucune position n\'est pas disponible.';
@override
String get failed_location =>
'Échec de récupération des données geographique';
@override
String get failed_fetch => 'Échec de récupération des routes';
@override
String get invalid_coordinates_symbol =>
'Coordonnées invalides. On ne peut pas ajouter le symbole';
@override
String get error_symbol => 'Erreur lors de l\'ajout du symbole';
@override
String get position_not_init =>
'Coordonnées non initialisées. Essaye encore.';
@override
String get invalid_coordinates => 'Coordonnées invalides';
@override
String get walking => 'Marche';
@override
String get cycling => 'Vélo';
@override
String get driving => 'Voiture';
@override
String get get_direction => 'Get Directions and Markers';
@override
String get missing_token => 'Token d\'accès manquant';
@override
String get geocoding_error => 'Erreur lors du geocodage';
@override
String get no_found_place => 'Lieu introuvable';
@override
String get upload_error => 'Erreur lors de l\'upload d\'image';
@override
String get event_added => 'Évènement ajouté';
@override
String get unknown_error => 'Erreur inconnue';
@override
String get app_error => 'Erreur d\'application';
@override
String get at => 'à';
@override
String get to_date => 'jusqu\'à';
@override
String get item_link => 'Lien : ';
@override
String get item_ticket => 'Billet : ';
@override
String get link => 'Lien';
@override
String get edit_link => 'Editer le lien';
@override
String get ticket => 'Billet';
@override
String get edit_ticket => 'Editer le lien du billet';
@override
String get toogle_interest => 'Erreur de bouton de changement';
@override
String get error_update => 'Erreur lors de la mise à jour';
@override
String get count_interested => 'Nombre de personne interessé';
}

View File

@@ -0,0 +1,143 @@
{
"@@locale": "de",
"menu_list": "Veranstaltungsmenü",
"language": "Sprache",
"home": "Startseite",
"settings": "Einstellungen",
"update_profile": "Profil aktualisieren",
"about": "Über",
"log_out": "Abmelden",
"french": "Französisch",
"english": "Englisch",
"german": "Deutsch",
"select_language": "Sprache auswählen",
"search_item": "Nach Element suchen",
"search_tag": "Nach Schlagwörtern suchen",
"search_geographical": "Nach geografischer Zone suchen",
"show_date_field": "Datumsfelder anzeigen",
"hide_date_field": "Datumsfelder ausblenden",
"no_data": "Keine Daten verfügbar",
"search": "Suchen",
"no_events": "Keine Veranstaltungen für diesen Ort verfügbar.",
"start_date": "Anfangsdatum",
"end_date": "Enddatum",
"failed_suggestions": "Vorschläge konnten nicht geladen werden",
"error": "Fehler",
"password_different": "Ein anderes Passwort eingeben",
"create": "Erstellung",
"user_create": "Benutzer wurde erstellt",
"user_update": "Benutzer wurde aktualisiert",
"request_error": "Fehlerhafte Anfrage",
"incorrect_password": "Falsches Passwort",
"unknown_user": "Unbekannter Benutzer",
"disabled_user": "Benutzer deaktiviert",
"invalid_token": "Ungültiger Token",
"internal_error_server": "Interner Serverfehler",
"unknown_error_auth": "Unbekannter Authentifizierungsfehler",
"required_input": "Pflichtfeld",
"create_profile": "Profil erstellen",
"edit_pseudo": "Benutzernamen bearbeiten",
"password": "Passwort",
"enter_password": "Passwort eingeben",
"password_confirmed": "Passwort bestätigt",
"last_name": "Nachname",
"first_name": "Vorname",
"email": "E-Mail",
"edit_last_name": "Nachnamen bearbeiten",
"edit_first_name": "Vornamen bearbeiten",
"edit_email": "E-Mail-Adresse bearbeiten",
"birth_date": "Geburtsdatum",
"edit_birth": "Geburtsdatum bearbeiten",
"create_profile_button": "Profil erstellen",
"take_picture": "Foto aufnehmen",
"error_ia": "Google KI konnte das Bild nicht analysieren. Bitte ein anderes versuchen.",
"no_data_geo": "Keine geografischen Daten",
"response_status_update": "Statuscode-Antwort aktualisieren",
"error_token": "Token-Fehler",
"error_format": "Vom KI geliefertes Datenformat ist fehlerhaft",
"display_picture": "Bild anzeigen",
"analyze_image": "Bildanalyse läuft",
"loading_progress": "Ladefortschritt",
"error_event": "Veranstaltungsfehler",
"no_future_event": "Keine zukünftigen Veranstaltungen",
"error_user": "Benutzerfehler",
"empty_input": "Eingabefeld leer",
"info_event": "Veranstaltungsinfo",
"event_already": "Veranstaltung existiert bereits",
"picture_error": "Bildfehler",
"no_picture_published": "Kein Bild veröffentlicht",
"event_update": "Veranstaltung aktualisiert",
"location": "Ort",
"add_event": "Veranstaltung hinzufügen oder aktualisieren",
"edit_image": "Bilder bearbeiten",
"name": "Name",
"edit_event_name": "Veranstaltungsname bearbeiten",
"start_time": "Startzeit",
"end_time": "Endzeit",
"select_date": "Zum Auswählen eines Datums klicken",
"select_time": "Zum Auswählen einer Uhrzeit klicken",
"tag": "Schlagwörter",
"already_tag": "Dieses Schlagwort ist bereits vorhanden",
"enter_tag": "Ein Schlagwort eingeben",
"organizer": "Veranstalter",
"already_organiser": "Veranstalter bereits vorhanden",
"enter_organizer": "Veranstalter eingeben",
"description": "Beschreibung",
"describe_event": "Veranstaltung beschreiben",
"add": "Hinzufügen",
"different_password_error": "Passwörter stimmen nicht überein",
"update": "Aktualisieren",
"updated": "Aktualisiert",
"settings_updated": "Einstellungen aktualisiert",
"define_kilometer": "Kilometer definieren",
"email_sent": "E-Mail wurde gesendet",
"forgot_password": "Passwort vergessen",
"enter_email": "E-Mail eingeben",
"send_email": "E-Mail senden",
"invalid_cache": "Ungültiger Cache",
"item_date": "Datum : ",
"item_maps": "Karte : ",
"item_organizer": "Veranstalter : ",
"item_description": "Beschreibung : ",
"item_tags": "Schlagwörter : ",
"failed_auth": "Authentifizierung fehlgeschlagen",
"login_page": "Anmeldeseite",
"pseudo": "Benutzername",
"enter_existing_pseudo": "Vorhandenen Benutzernamen eingeben",
"remembr_me": "Angemeldet bleiben",
"new_user": "Neuer Benutzer? Konto erstellen",
"sign_in": "Anmelden",
"map_token": "Mapbox-Zugangstoken ist nicht verfügbar",
"geo_disabled": "Standortdienste sind deaktiviert.",
"permission_denied": "Standortberechtigungen wurden verweigert.",
"enable_permission": "Standortberechtigungen dauerhaft verweigert. Bitte in den Einstellungen aktivieren.",
"no_last_position": "Keine letzte bekannte Position verfügbar.",
"failed_location": "Standort konnte nicht ermittelt werden",
"failed_fetch": "Route konnte nicht abgerufen werden",
"invalid_coordinates_symbol": "Ungültige Koordinaten, Symbol kann nicht hinzugefügt werden.",
"error_symbol": "Fehler beim Hinzufügen des Symbols.",
"position_not_init": "Benutzerposition noch nicht initialisiert. Erneut versuchen.",
"invalid_coordinates": "Ungültige Koordinaten.",
"walking": "Zu Fuß",
"cycling": "Mit dem Fahrrad",
"driving": "Mit dem Auto",
"get_direction": "Wegbeschreibung und Markierungen anzeigen",
"missing_token": "Zugangstoken fehlt",
"geocoding_error": "Fehler bei der Geokodierung",
"no_found_place": "Kein Ort gefunden",
"upload_error": "Fehler beim Hochladen des Bildes",
"event_added": "Veranstaltung hinzugefügt",
"unknown_error": "Unbekannter Fehler",
"app_error": "Anwendungsfehler",
"at": "um",
"to_date": "bis",
"item_link": "Link : ",
"item_ticket": "Abendkarte : ",
"link": "Link",
"edit_link": "Linkereignis bearbeiten",
"ticket": "Abendkarte",
"edit_ticket": "Ticketlink bearbeiten",
"toogle_interest": "Fehler beim Umschalten des Interesses",
"error_update": "Fehler beim Update",
"count_interested": "Anzahl der Interessenten"
}

View File

@@ -0,0 +1,145 @@
{
"@@locale": "en",
"menu_list": "Event list menu",
"language": "Language",
"home": "Home",
"settings": "Settings",
"update_profile": "Update profile",
"about": "About",
"log_out": "Log out",
"french": "French",
"english": "English",
"german": "German",
"select_language": "Select language",
"search_item": "Search by item",
"search_tag": "Search by tags",
"search_geographical": "Search by geographical zone",
"show_date_field": "Show Date Fields",
"hide_date_field": "Hide Date Fields",
"no_data": "No data available",
"search": "Search",
"no_events": "No events available for this location.",
"start_date": "Start date",
"end_date": "End date",
"failed_suggestions": "Failed to load suggestions",
"error":"Error",
"password_different":"Must write a different password",
"create": "Creation",
"user_create": "Your user created",
"user_update": "Your user updated",
"request_error": "Poorly constructed query",
"incorrect_password": "Incorrect password",
"unknown_user": "Unknown user",
"disabled_user": "User disabled",
"invalid_token": "Invalid token",
"internal_error_server": "Internal error server",
"unknown_error_auth": "Unknown error authentification",
"required_input": "Required input",
"create_profile": "Create profile",
"edit_pseudo": "Edit pseudo",
"password":"Password",
"enter_password": "Enter the passord",
"password_confirmed": "Password confirmed",
"last_name": "Last name",
"first_name": "First name",
"email": "Mail",
"edit_last_name": "Edit name",
"edit_first_name": "Edit first name",
"edit_email": "Edit email address",
"birth_date": "Birth date",
"edit_birth": "Edit birth date",
"create_profile_button": "Create profile",
"take_picture": "Take a picture",
"error_ia": "Google AI failed to analyze picture. Retry with another one",
"no_data_geo": "No geographical data",
"response_status_update": "response status code update",
"error_token": "Token error",
"error_format": "Data format error given by AI",
"display_picture": "Display the Picture",
"analyze_image": "Image Analyze in progress",
"loading_progress": "Loading progress",
"error_event": "Event error",
"no_future_event": "No future event",
"error_user": "Error user",
"empty_input": "Empty input",
"info_event": "Event info",
"event_already": "Event already exists",
"picture_error": "Picture error",
"no_picture_published": "No picture published",
"event_update": "Event updated",
"location": "Location",
"add_event": "Add or Update a event",
"edit_image": "Edit pictures",
"name": "Name",
"edit_event_name": "Edit event name",
"start_time": "Start time",
"end_time": "End time",
"select_date": "Click to select a date",
"select_time": "Click to select a time",
"tag": "Tags",
"already_tag": "You have already this tags",
"enter_tag": "Enter a tag",
"organizer": "Organizer",
"already_organiser": "You have already a organizer",
"enter_organizer": "Enter a organizer",
"description": "Description",
"describe_event": "Describe event",
"add": "Add",
"update_profile": "Update profile",
"different_password_error": "Different password",
"update": "Update",
"updated": "Updated",
"settings_updated": "Settings updated",
"define_kilometer": "Define Kilometer",
"settings": "Settings",
"email_sent": "Email has been sent",
"forgot_password": "Forgot password",
"enter_email": "Enter the email",
"send_email": "Send email",
"invalid_cache": "Invalid cache",
"item_date": "Date : ",
"item_maps": "Maps : ",
"item_organizer": "Organizer : ",
"item_description": "Description : ",
"item_tags": "Tags : ",
"failed_auth": "Authentification failed",
"login_page": "Login page",
"pseudo": "Pseudo",
"enter_existing_pseudo": "Enter a existing pseudo",
"remembr_me": "Remember me",
"new_user": "New User? Create Account",
"sign_in": "Sign in",
"map_token": "Mapbox Access Token is not available",
"geo_disabled": "Location services are disabled.",
"permission_denied":"Location permissions are denied.",
"enable_permission": "Location permissions are permanently denied. Enable them in settings.",
"no_last_position": "No last known position available.",
"failed_location": "Failed to get user location",
"failed_fetch": "Failed to fetch the route",
"invalid_coordinates_symbol": "Invalid coordinates, cannot add symbol.",
"error_symbol": "Error when adding symbol.",
"position_not_init": "User position is not yet initialized. Try again.",
"invalid_coordinates": "Invalid coordinates.",
"walking": "Walking",
"cycling": "Cycling",
"driving": "Driving",
"get_direction": "Get Directions and Markers",
"missing_token": "Missing access token",
"geocoding_error": "Error when geocoding",
"no_found_place": "No found place",
"upload_error": "Error when image uploading",
"event_added": "Event added",
"unknown_error": "Unknown error",
"app_error": "Application error",
"at": "at",
"to_date": "to",
"item_link": "Link : ",
"item_ticket": "Ticket : ",
"link": "Link",
"edit_link": "Edit link name",
"ticket": "Ticket",
"edit_ticket": "Edit ticket link",
"toogle_interest": "Error toggle interest",
"error_update": "Error when updating",
"count_interested": "Interested people number"
}

View File

@@ -0,0 +1,146 @@
{
"@@locale": "fr",
"menu_list": "Liste d'évènement",
"language": "Langue",
"home": "Accueil",
"settings": "Paramètres",
"update_profile": "Modifier profil",
"about": "À propos",
"log_out": "Se déconnecter",
"french": "Français",
"english": "Anglais",
"german": "Allemand",
"select_language": "Selectionne la langue",
"search_item": "Recherche par item",
"search_tag": "Recherche par tags",
"search_geographical": "Recherche par zone géographique",
"show_date_field": "Afficher champ date",
"hide_date_field": "Cacher Date Fields",
"no_data": "Aucune donnée disponible",
"search": "Recherche",
"no_events": "Pas d'évènements dans cette localisation",
"start_date": "Date de début",
"end_date": "Date de fin",
"failed_suggestions": "Echec de chargement des suggestions",
"error":"Erreur",
"password_different":"Tu dois écrire un mot de passe different",
"create": "Création",
"user_create": "Votre utilisateur a été créé",
"user_update": "Votre utilisateur a été modifié",
"request_error": "Requête mal construite",
"incorrect_password": "Mot de passe incorrect",
"unknown_user": "Utilisateur inconnu",
"disabled_user": "Utilisateur désactivé",
"invalid_token": "Token invalide",
"internal_error_server": "Erreur interne de serveur",
"unknown_error_auth": "Problème d'authentification inconnu",
"required_input": "Champ requis",
"create_profile": "Creation profil",
"edit_pseudo": "Modifier le pseudo",
"password":"Mot de passe",
"enter_password": "Entrez le password",
"password_confirmed": "Confirmez le mot de passe",
"last_name": "Nom",
"first_name": "Prénom",
"email": "Email",
"edit_last_name": "Modifier le nom",
"edit_first_name": "Modifier le prénom",
"edit_email": "Modifier l'email",
"birth_date": "Date de naissance",
"edit_birth": "Modifier la date de naissance",
"create_profile_button": "Créer le profil",
"take_picture": "Take a picture",
"error_ia": "L'IA de Google n'a pas su analyser l'image. Recommencer avec une autre",
"no_data_geo": "Aucune donnée géographique",
"response_status_update": "Code du statut de réponse de la modification",
"error_token": "Erreur de token",
"error_format": "Erreur de format de donnée fourni par l'IA",
"display_picture": "Display the Picture",
"analyze_image": "Analyse de l'image en cours",
"loading_progress": "Chargement en cours",
"error_event": "Erreur de l'évènement",
"no_future_event": "Évènement non futur",
"error_user": "Erreur de l'utilisateur",
"empty_input": "Champ vide",
"info_event": "Event info",
"event_already": "Event already exists",
"picture_error": "Erreur image",
"no_picture_published": "Image non publiée",
"event_update": "Évènement modifié",
"location": "Lieu",
"add_event": "Ajouter ou modifier un évènement",
"edit_image": "Changer la photo",
"name": "Nom",
"edit_event_name": "Changer le nom de l'évènement",
"start_time": "Heure de début",
"end_time": "Heure de fin",
"select_date": "Cliquer pour selectionner une date",
"select_time": "Cliquer pour selectionner une heure",
"tag": "Tags",
"already_tag": "Tu as déjà entré ce tag",
"enter_tag": "Entrer un tag",
"organizer": "Organisateur",
"already_organiser": "Tu as déjà rentré cet organisateur",
"enter_organizer": "Entrer un organisateur",
"description": "Description",
"describe_event": "Décrire l'évènement",
"add": "Ajouter",
"update_profile": "Modifier le profil",
"different_password_error": "Mot de passe différent",
"update": "Mettre à jour",
"updated": "Mis à jour",
"settings_updated": "Paramètre mis à jour",
"define_kilometer": "Definir un kilomètre",
"settings": "Paramètres",
"email_sent": "Email a été envoyé",
"forgot_password": "Mot de passe oublié",
"enter_email": "Entrez l'email",
"send_email": "Send email",
"invalid_cache": "Cache invalide",
"item_date": "Date : ",
"item_maps": "Carte : ",
"item_organizer": "Organisateurs : ",
"item_description": "Description : ",
"item_tags": "Tags : ",
"failed_auth": "Échec de l'authenticaton",
"login_page": "Page d'authentification",
"pseudo": "Pseudo",
"enter_existing_pseudo": "Entrez un pseudo existant",
"remembr_me": "Se souvenir de moi",
"new_user": "Nouvel utilisateur ? Créer un compte",
"sign_in": "Se connecter",
"map_token": "Token d'accès de Mapbox n'est pas disponible",
"geo_disabled": "Les services de localisation sont désactivés.",
"permission_denied":"Les permissions de localisation sont refusées.",
"enable_permission": "Les permissions de localisation sont toujours désactivés. Il faut les désactiver",
"no_last_position": "Aucune position n'est pas disponible.",
"failed_location": "Échec de récupération des données geographique",
"failed_fetch": "Échec de récupération des routes",
"invalid_coordinates_symbol": "Coordonnées invalides. On ne peut pas ajouter le symbole",
"error_symbol": "Erreur lors de l'ajout du symbole",
"position_not_init": "Coordonnées non initialisées. Essaye encore.",
"invalid_coordinates": "Coordonnées invalides",
"walking": "Marche",
"cycling": "Vélo",
"driving": "Voiture",
"get_direction": "Get Directions and Markers",
"missing_token": "Token d'accès manquant",
"geocoding_error": "Erreur lors du geocodage",
"no_found_place": "Lieu introuvable",
"upload_error": "Erreur lors de l'upload d'image",
"event_added": "Évènement ajouté",
"unknown_error": "Erreur inconnue",
"app_error": "Erreur d'application",
"at": "à",
"to_date": "jusqu'à",
"item_link": "Lien : ",
"item_ticket": "Billet : ",
"link": "Lien",
"edit_link": "Editer le lien",
"ticket": "Billet",
"edit_ticket": "Editer le lien du billet",
"toogle_interest": "Erreur de bouton de changement",
"error_update": "Erreur lors de la mise à jour",
"count_interested": "Nombre de personne interessé"
}

View File

@@ -0,0 +1,41 @@
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
class LocaleProvider with ChangeNotifier {
static const _localeKey = 'locale_code';
Locale _locale = const Locale('en');
Locale get locale => _locale;
LocaleProvider() {
_loadLocale();
}
Future<void> _loadLocale() async {
final prefs = await SharedPreferences.getInstance();
final code = prefs.getString(_localeKey);
if (code != null && L10n.all.contains(Locale(code))) {
_locale = Locale(code);
notifyListeners();
}
}
void setLocale(Locale locale) async {
if (!L10n.all.contains(locale)) return;
_locale = locale;
notifyListeners();
final prefs = await SharedPreferences.getInstance();
await prefs.setString(_localeKey, locale.languageCode);
}
}
class L10n {
static final all = [
const Locale('en'),
const Locale('fr'),
const Locale('de')
];
}

View File

@@ -0,0 +1,43 @@
import 'package:flutter/material.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:provider/provider.dart';
import 'pages/LoginDemo.dart';
import 'locale_provider.dart'; // <-- à adapter selon ton arborescence
import 'package:covas_mobile/gen_l10n/app_localizations.dart';
import 'classes/notification_service.dart';
import 'classes/auth_service.dart';
import 'pages/ListItemMenu.dart';
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await MobileAds.instance.initialize();
await NotificationService.initialize();
final AuthService _authService = AuthService();
final loggedIn = await _authService.isLoggedIn();
runApp(
ChangeNotifierProvider(
create: (_) => LocaleProvider(),
child: MyApp(isLoggedIn: loggedIn),
),
);
}
class MyApp extends StatelessWidget {
final bool isLoggedIn;
const MyApp({Key? key, required this.isLoggedIn}) : super(key: key);
@override
Widget build(BuildContext context) {
final localeProvider = Provider.of<LocaleProvider>(
context); // écoute les changements de langue
return MaterialApp(
debugShowCheckedModeBanner: false,
locale: localeProvider.locale, // <-- utilise la locale courante
supportedLocales: L10n.all,
localizationsDelegates: AppLocalizations.localizationsDelegates,
home: isLoggedIn ? ListItemMenu() : LoginDemo(),
);
}
}

View File

@@ -0,0 +1,335 @@
import 'package:flutter/material.dart';
import 'package:http/http.dart' as http;
import 'package:intl/intl.dart';
import 'dart:convert';
import 'dart:io';
import '../pages/LoginDemo.dart';
import '../classes/alert.dart';
import '../variable/globals.dart' as globals;
import '../classes/ad_helper.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:covas_mobile/gen_l10n/app_localizations.dart';
import 'package:provider/provider.dart';
import '../locale_provider.dart'; // Créé plus loin
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await MobileAds.instance.initialize();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: AddProfile(),
);
}
}
class AddProfile extends StatefulWidget {
const AddProfile({super.key});
@override
_AddProfileState createState() => _AddProfileState();
}
class _AddProfileState extends State<AddProfile> with ShowAlertDialog {
BannerAd? _bannerAd;
TextEditingController inputUserName = TextEditingController();
TextEditingController inputName = TextEditingController();
TextEditingController inputFirstName = TextEditingController();
TextEditingController inputEmail = TextEditingController();
TextEditingController inputBirth = TextEditingController();
TextEditingController inputPassword = TextEditingController();
TextEditingController inputPasswordConfirmed = TextEditingController();
onTapFunctionDatePicker({required BuildContext context}) async {
DateTime? pickedDate = await showDatePicker(
context: context,
firstDate: DateTime(1900),
initialDate: DateTime.now(),
lastDate: DateTime(2104));
if (pickedDate == null) return;
inputBirth.text = DateFormat("dd/MM/yyyy").format(pickedDate);
}
convertNulltoEmptyString(var check) {
if (check == null) {
return "";
}
return check;
}
convertNulltoArray(List<String> check) {
if (check == null) {
return [];
}
return check;
}
String formatDate(String date) {
var splitedDate = date.split("/");
var day = splitedDate[0];
var month = splitedDate[1];
var year = splitedDate[2];
return "${year}-${month}-${day}";
}
Future<void> _createProfile(BuildContext context) async {
var username = inputUserName.text;
var firstName = inputFirstName.text;
var name = inputName.text;
var email = inputEmail.text;
var password = inputPassword.text;
var confirmedPassword = inputPasswordConfirmed.text;
var birth = DateTime.parse(formatDate(inputBirth.text));
if ((password.isNotEmpty) && (confirmedPassword.isNotEmpty)) {
if (password != confirmedPassword) {
showAlertDialog(
context,
AppLocalizations.of(context)?.error ?? "Error",
AppLocalizations.of(context)?.password_different ??
"Must write a different password");
return;
}
}
var urlPut = Uri.parse("${globals.api}/mail");
var responsePost = await http.post(urlPut,
headers: {
HttpHeaders.acceptHeader: 'application/json, text/plain, */*',
HttpHeaders.contentTypeHeader: 'application/json'
},
body: jsonEncode({
'name': name,
'username': username,
'firstName': firstName,
'password': password,
'email': email,
'birth': birth.toString()
}));
print(responsePost.statusCode);
if (responsePost.statusCode == 200) {
showAlertDialog(
context,
AppLocalizations.of(context)?.create ?? "Creation",
AppLocalizations.of(context)?.user_create ?? "Your user created");
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (_) => LoginDemo()));
return;
}
final errorMessages = {
400: AppLocalizations.of(context)?.request_error ??
"Poorly constructed query",
406: AppLocalizations.of(context)?.incorrect_password ??
"Incorrect password",
404: AppLocalizations.of(context)?.unknown_user ?? "Unknown user",
403: AppLocalizations.of(context)?.disabled_user ?? "Disabled user",
410: AppLocalizations.of(context)?.invalid_token ?? "Invalid token",
500: AppLocalizations.of(context)?.internal_error_server ??
"Internal error server"
};
final text = errorMessages[responsePost.statusCode] ??
AppLocalizations.of(context)?.unknown_error_auth ??
"Unknown error auth";
showAlertDialog(
context, AppLocalizations.of(context)?.error ?? "Error", text);
}
@override
void initState() {
super.initState();
AdHelper.createBannerAd(() => setState(() {})).then((ad) {
setState(() {
_bannerAd = ad;
});
});
}
final _formKey = GlobalKey<FormState>();
String? _validateField(String? value) {
return value!.isEmpty
? AppLocalizations.of(context)?.required_input ?? 'Required input'
: null;
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text(
AppLocalizations.of(context)?.create_profile ?? "Create profile"),
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
),
body: Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
_bannerAd == null
? SizedBox.shrink()
: SizedBox(
height: _bannerAd!.size.height.toDouble(),
width: _bannerAd!.size.width.toDouble(),
child: AdWidget(ad: _bannerAd!)),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextFormField(
controller: inputUserName,
validator: (value) => _validateField(value),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: 'Pseudo',
hintText: AppLocalizations.of(context)?.edit_pseudo ??
'Edit pseudo'),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextFormField(
controller: inputPassword,
validator: (value) => _validateField(value),
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: AppLocalizations.of(context)?.password ??
'Password',
hintText:
AppLocalizations.of(context)?.enter_password ??
'Enter the password'),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextFormField(
controller: inputPasswordConfirmed,
validator: (value) => _validateField(value),
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText:
AppLocalizations.of(context)?.password_confirmed ??
'Password confirmed',
hintText:
AppLocalizations.of(context)?.password_confirmed ??
'Password confirmed',
),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextFormField(
controller: inputName,
validator: (value) => _validateField(value),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: AppLocalizations.of(context)?.last_name ??
'Last name',
hintText:
AppLocalizations.of(context)?.edit_last_name ??
'Edit last name'),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextFormField(
controller: inputFirstName,
validator: (value) => _validateField(value),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: AppLocalizations.of(context)?.first_name ??
'First name',
hintText:
AppLocalizations.of(context)?.edit_first_name ??
'Edit first name'),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextFormField(
controller: inputEmail,
validator: (value) => _validateField(value),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText:
AppLocalizations.of(context)?.email ?? 'Email',
hintText: AppLocalizations.of(context)?.edit_email ??
'Edit email'),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextFormField(
controller: inputBirth,
readOnly: true,
validator: (value) => _validateField(value),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: AppLocalizations.of(context)?.birth_date ??
'Birth date',
hintText: AppLocalizations.of(context)?.edit_birth ??
'Edit birth date'),
onTap: () => onTapFunctionDatePicker(context: context)),
),
SizedBox(
height: 30,
),
Container(
height: 50,
width: 250,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(20)),
child: TextButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
_createProfile(context);
}
},
child: Text(
AppLocalizations.of(context)?.create_profile_button ??
"Create profile",
style: TextStyle(color: Colors.white, fontSize: 25),
),
),
)
],
),
),
));
}
}

View File

@@ -0,0 +1,163 @@
import 'dart:async';
import 'package:image_picker/image_picker.dart';
import '../classes/MyDrawer.dart';
import 'DisplayPictureScreen.dart';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import '../classes/auth_service.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:covas_mobile/gen_l10n/app_localizations.dart';
import 'package:provider/provider.dart';
import '../locale_provider.dart'; // Créé plus loin
Future<void> main() async {
// Ensure that plugin services are initialized so that `availableCameras()`
// can be called before `runApp()`
WidgetsFlutterBinding.ensureInitialized();
// Obtain a list of the available cameras on the device.
final cameras = await availableCameras();
// Get a specific camera from the list of available cameras.
final firstCamera = cameras.first;
runApp(
MaterialApp(
theme: ThemeData.dark(),
home: Camera(
// Pass the appropriate camera to the TakePictureScreen widget.
camera: firstCamera,
),
),
);
}
// A screen that allows users to take a picture using a given camera.
class Camera extends StatefulWidget {
const Camera({
super.key,
required this.camera,
});
final CameraDescription camera;
@override
CameraState createState() => CameraState();
}
class CameraState extends State<Camera> {
late CameraController _controller;
late Future<void> _initializeControllerFuture;
final AuthService _authService = AuthService();
@override
void initState() {
super.initState();
// To display the current output from the Camera,
// create a CameraController.
_authService.checkTokenStatus(context);
_controller = CameraController(
// Get a specific camera from the list of available cameras.
widget.camera,
// Define the resolution to use.
ResolutionPreset.medium,
);
// Next, initialize the controller. This returns a Future.
_initializeControllerFuture = _controller.initialize();
}
Future<void> pickImage() async {
final imagePicker = ImagePicker();
final pickedFile = await imagePicker.pickImage(source: ImageSource.gallery);
if (pickedFile != null) {
await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => DisplayPictureScreen(
// Pass the automatically generated path to
// the DisplayPictureScreen widget.
imagePath: pickedFile.path,
),
),
);
}
}
@override
void dispose() {
// Dispose of the controller when the widget is disposed.
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context)?.take_picture ??
"Take a picture")),
// You must wait until the controller is initialized before displaying the
// camera preview. Use a FutureBuilder to display a loading spinner until the
// controller has finished initializing.
drawer: MyDrawer(),
body: FutureBuilder<void>(
future: _initializeControllerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// If the Future is complete, display the preview.
return CameraPreview(_controller);
} else {
// Otherwise, display a loading indicator.
return const Center(child: CircularProgressIndicator());
}
},
),
floatingActionButton: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FloatingActionButton(
onPressed: pickImage,
child: Icon(Icons.photo_library),
),
SizedBox(width: 40),
FloatingActionButton(
// Provide an onPressed callback.
onPressed: () async {
// Take the Picture in a try / catch block. If anything goes wrong,
// catch the error.
try {
// Ensure that the camera is initialized.
await _initializeControllerFuture;
// Attempt to take a picture and get the file `image`
// where it was saved.
final image = await _controller.takePicture();
if (!context.mounted) return;
// If the picture was taken, display it on a new screen.
await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => DisplayPictureScreen(
// Pass the automatically generated path to
// the DisplayPictureScreen widget.
imagePath: image.path,
),
),
);
} catch (e) {
// If an error occurs, log the error to the console.
print(e);
}
},
child: const Icon(Icons.camera_alt),
)
],
)));
}
}

View File

@@ -0,0 +1,166 @@
import 'dart:async';
import 'dart:io';
import '../classes/events.dart';
import '../classes/MyDrawer.dart';
import 'package:image_picker/image_picker.dart';
import 'EditEvent.dart';
import 'package:camera/camera.dart';
import 'package:flutter/material.dart';
import '../classes/auth_service.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:covas_mobile/gen_l10n/app_localizations.dart';
import 'package:provider/provider.dart';
import '../locale_provider.dart'; // Créé
Future<void> main() async {
// Ensure that plugin services are initialized so that `availableCameras()`
// can be called before `runApp()`
WidgetsFlutterBinding.ensureInitialized();
// Obtain a list of the available cameras on the device.
final cameras = await availableCameras();
// Get a specific camera from the list of available cameras.
final firstCamera = cameras.first;
Events? events;
runApp(
MaterialApp(
theme: ThemeData.dark(),
home: CameraEdit(
// Pass the appropriate camera to the TakePictureScreen widget.
camera: firstCamera,
events: events),
),
);
}
// A screen that allows users to take a picture using a given camera.
class CameraEdit extends StatefulWidget {
const CameraEdit({super.key, required this.camera, required this.events});
final Events? events;
final CameraDescription camera;
@override
CameraEditState createState() => CameraEditState();
}
class CameraEditState extends State<CameraEdit> {
late CameraController _controller;
late Future<void> _initializeControllerFuture;
final AuthService _authService = AuthService();
@override
void initState() {
super.initState();
_authService.checkTokenStatus(context);
// To display the current output from the Camera,
// create a CameraController.
_controller = CameraController(
// Get a specific camera from the list of available cameras.
widget.camera,
// Define the resolution to use.
ResolutionPreset.medium,
);
// Next, initialize the controller. This returns a Future.
_initializeControllerFuture = _controller.initialize();
}
Future<void> pickImage() async {
final imagePicker = ImagePicker();
final pickedFile = await imagePicker.pickImage(source: ImageSource.gallery);
if (pickedFile != null) {
await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => EditEvent(
// Pass the automatically generated path to
// the DisplayPictureScreen widget.
events: widget.events,
imgPath: pickedFile.path,
),
),
);
}
}
@override
void dispose() {
// Dispose of the controller when the widget is disposed.
_controller.dispose();
super.dispose();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context)?.take_picture ??
'Take a picture')),
// You must wait until the controller is initialized before displaying the
// camera preview. Use a FutureBuilder to display a loading spinner until the
// controller has finished initializing.
drawer: MyDrawer(),
body: FutureBuilder<void>(
future: _initializeControllerFuture,
builder: (context, snapshot) {
if (snapshot.connectionState == ConnectionState.done) {
// If the Future is complete, display the preview.
return CameraPreview(_controller);
} else {
// Otherwise, display a loading indicator.
return const Center(child: CircularProgressIndicator());
}
},
),
floatingActionButton: Padding(
padding: const EdgeInsets.all(8.0),
child: Row(
mainAxisAlignment: MainAxisAlignment.center,
children: <Widget>[
FloatingActionButton(
onPressed: pickImage,
child: Icon(Icons.photo_library),
),
SizedBox(width: 40),
FloatingActionButton(
// Provide an onPressed callback.
onPressed: () async {
// Take the Picture in a try / catch block. If anything goes wrong,
// catch the error.
try {
// Ensure that the camera is initialized.
await _initializeControllerFuture;
// Attempt to take a picture and get the file `image`
// where it was saved.
final image = await _controller.takePicture();
if (!context.mounted) return;
// If the picture was taken, display it on a new screen.
await Navigator.of(context).push(
MaterialPageRoute(
builder: (context) => EditEvent(
// Pass the automatically generated path to
// the DisplayPictureScreen widget.
events: widget.events,
imgPath: image.path,
),
),
);
} catch (e) {
// If an error occurs, log the error to the console.
print(e);
}
},
child: const Icon(Icons.camera_alt),
)
],
)));
}
}

View File

@@ -0,0 +1,266 @@
import 'package:flutter/material.dart';
import 'dart:io';
import '../classes/addEventImage.dart';
import '../classes/alert.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:flutter_gemini/flutter_gemini.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
import "ItemMenu.dart";
import 'UpdateEventImage.dart';
import 'dart:convert';
import '../variable/globals.dart' as globals;
import '../classes/MyDrawer.dart';
import '../classes/ad_helper.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import '../classes/auth_service.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:covas_mobile/gen_l10n/app_localizations.dart';
import 'package:provider/provider.dart';
import '../locale_provider.dart'; // Créé
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await MobileAds.instance.initialize();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
const MyApp({Key? key}) : super(key: key);
// This widget is the root of your application.
@override
Widget build(BuildContext context) {
return MaterialApp(
title: 'Flutter Demo',
theme: ThemeData(
// This is the theme of your application.
//
// Try running your application with "flutter run". You'll see the
// application has a blue toolbar. Then, without quitting the app, try
// changing the primarySwatch below to Colors.green and then invoke
// "hot reload" (press "r" in the console where you ran "flutter run",
// or simply save your changes to "hot reload" in a Flutter IDE).
// Notice that the counter didn't reset back to zero; the application
// is not restarted.
primarySwatch: Colors.blue,
),
);
}
}
// A screen that allows users to take a picture using a given camera.
class DisplayPictureScreen extends StatefulWidget {
final String imagePath;
const DisplayPictureScreen({super.key, required this.imagePath});
@override
DisplayPictureScreenState createState() => DisplayPictureScreenState();
}
// A widget that displays the picture taken by the user.
class DisplayPictureScreenState extends State<DisplayPictureScreen>
with ShowDescImageAdd, ShowAlertDialog, TickerProviderStateMixin {
BannerAd? _bannerAd;
final AuthService _authService = AuthService();
late AnimationController controller;
@override
void initState() {
super.initState();
_authService.checkTokenStatus(context);
AdHelper.createBannerAd(() => setState(() {})).then((ad) {
setState(() {
_bannerAd = ad;
});
});
controller = AnimationController(
/// [AnimationController]s can be created with `vsync: this` because of
/// [TickerProviderStateMixin].
vsync: this,
duration: const Duration(seconds: 5),
)..addListener(() {
setState(() {});
});
controller.repeat(reverse: false);
_getEventInfosFromImage();
}
@override
void dispose() {
controller.dispose();
super.dispose();
}
Future<void> displayError(String e) async {
print("problem gemini : ${e}");
showAlertDialog(
context,
AppLocalizations.of(context)?.error ?? 'Error',
AppLocalizations.of(context)?.error_ia ??
'Google AI failed to analyze picture. Retry with another one');
}
void _showErrorDialog(BuildContext context, String title, String message) {
showAlertDialog(context, title, message);
}
Future<Map<String, dynamic>?> _fetchGeolocation(String place) async {
final apiKey = dotenv.env['PLACE_API_KEY'] ?? '';
final response = await http.get(Uri.parse(
'https://maps.googleapis.com/maps/api/place/textsearch/json?query=${place}}&key=$apiKey'));
if (response.statusCode == 200) {
final data = json.decode(response.body);
if (data['results'].isNotEmpty) {
return data['results'][0]['geometry']['location'];
}
}
return null;
}
Future<bool> _isDuplicateEvent(String accessToken,
Map<String, dynamic> jsonData, Map<String, dynamic> location) async {
final url = Uri.parse(
"${globals.api}/events/search?item=${jsonData["name"]}&date_event=${jsonData["start_date"]}"
"&min_lat=${location['lat']}&max_lat=${location['lat']}"
"&min_lon=${location['lng']}&max_lon=${location['lng']}");
final response = await http.get(url,
headers: {HttpHeaders.cookieHeader: 'access_token=$accessToken'});
if (response.statusCode == 200) {
final events = jsonDecode(utf8.decode(response.bodyBytes));
return events.isNotEmpty;
}
return false;
}
Future<void> searchEvents(String json, String imagePath) async {
print(json.replaceAll("'''json", '').replaceAll("'''", ""));
SharedPreferences prefs = await SharedPreferences.getInstance();
try {
Map<String, dynamic> jsonData =
jsonDecode(json.replaceAll("```json", '').replaceAll("```", ""));
print("json : ${jsonData}");
var name = jsonData["name"];
print("name : ${name}");
var place = jsonData["place"];
var date = jsonData["start_date"];
var accessToken = prefs.getString("access_token") ?? "";
if (accessToken.isNotEmpty) {
final location = await _fetchGeolocation(place);
if (location == null) {
_showErrorDialog(
context,
AppLocalizations.of(context)?.error ?? 'Error',
AppLocalizations.of(context)?.no_data_geo ??
'No geographical data');
return;
}
final url = Uri.parse(
"${globals.api}/events/search?item=${name}&date_event=${date}"
"&min_lat=${location['lat']}&max_lat=${location['lat']}"
"&min_lon=${location['lng']}&max_lon=${location['lng']}");
final response = await http.get(url,
headers: {HttpHeaders.cookieHeader: 'access_token=$accessToken'});
if (response.statusCode == 200) {
var events = jsonDecode(utf8.decode(response.bodyBytes));
print("reponse http : ${events.length}");
if (events.length == 0) {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => UpdateeventImage(
events: jsonData, imagePath: imagePath)));
} else {
Navigator.push(
context,
MaterialPageRoute(
builder: (_) => ItemMenu(title: events[0]["id"])));
}
} else {
String error = AppLocalizations.of(context)?.response_status_update ??
'Response status update : ${response.statusCode}';
showAlertDialog(
context,
AppLocalizations.of(context)?.error ?? 'Error',
"${error} : ${response.statusCode}");
}
} else {
showAlertDialog(context, AppLocalizations.of(context)?.error ?? 'Error',
AppLocalizations.of(context)?.error_token ?? "Token error");
}
} catch (e) {
showAlertDialog(
context,
AppLocalizations.of(context)?.error ?? "Error",
AppLocalizations.of(context)?.error_format ??
"Data format error given by AI");
}
//showDescImageAddDialog(context, message);
}
Future<void> _getEventInfosFromImage() async {
await dotenv.load();
final gemini = Gemini.init(
apiKey: dotenv.env['GEMINI_API_KEY']!, enableDebugging: true);
final file = File(widget.imagePath);
gemini.prompt(parts: [
Part.text(
"Peux-tu donner le nom, la date (si l'année n'est pas précisé, mettez l'année actuelle ou future) et le lieu de l'évènement sous format JSON (sans le caratère json au début de la chaine de caractère) avec les valeurs suivantes : name, place, description, tags (tableau sans espace), organizers (tableau), start_date et end_date (si le end_date est vide, alors donnez une valeur de six de plus par rapport à start_date) sous le format en YYYY-MM-DD HH:mm:ssZ"),
Part.bytes(file.readAsBytesSync())
], model: "models/gemini-1.5-pro-latest").then((value) {
searchEvents(value?.output ?? '', widget.imagePath);
}).catchError((e) => displayError);
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: Text(AppLocalizations.of(context)?.display_picture ??
"Display The Picture")),
// The image is stored as a file on the device. Use the `Image.file`
// constructor with the given path to display the image.
drawer: MyDrawer(),
body: Padding(
padding: const EdgeInsets.all(20.0),
child: Column(
mainAxisAlignment: MainAxisAlignment.spaceEvenly,
children: <Widget>[
_bannerAd == null
? SizedBox.shrink()
: SizedBox(
height: _bannerAd!.size.height.toDouble(),
width: _bannerAd!.size.width.toDouble(),
child: AdWidget(ad: _bannerAd!)),
Text(
AppLocalizations.of(context)?.analyze_image ??
'Image analyze in progress',
style: Theme.of(context).textTheme.titleLarge,
),
CircularProgressIndicator(
value: controller.value,
semanticsLabel:
AppLocalizations.of(context)?.loading_progress ??
'Loading progress',
),
])));
}
}

View File

@@ -0,0 +1,921 @@
import 'package:covas_mobile/pages/CameraEdit.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
import 'package:intl/intl.dart';
import 'package:flutter_dotenv/flutter_dotenv.dart';
import 'package:textfield_tags/textfield_tags.dart';
import 'dart:convert';
import 'dart:io';
import '../classes/events.dart';
import '../classes/MyDrawer.dart';
import 'package:camera/camera.dart';
import '../classes/alert.dart';
import '../classes/eventAdded.dart';
import '../variable/globals.dart' as globals;
import '../classes/ad_helper.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import '../classes/auth_service.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:covas_mobile/gen_l10n/app_localizations.dart';
import 'package:provider/provider.dart';
import '../locale_provider.dart'; // Créé
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await MobileAds.instance.initialize();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
Events? events;
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: EditEvent(
events: events,
imgPath: "",
),
);
}
}
class EditEvent extends StatefulWidget {
const EditEvent({Key? key, required this.events, required this.imgPath})
: super(key: key);
final Events? events;
final String imgPath;
@override
_EditEventState createState() => _EditEventState();
}
class _EditEventState extends State<EditEvent>
with ShowAlertDialog, ShowEventDialog {
BannerAd? _bannerAd;
final AuthService _authService = AuthService();
TextEditingController inputName = TextEditingController();
TextEditingController inputTicket = TextEditingController();
TextEditingController inputLink = TextEditingController();
TextEditingController inputDate = TextEditingController();
TextEditingController inputDesc = TextEditingController();
TextEditingController inputGeo = TextEditingController();
TextEditingController startDatepicker = TextEditingController();
TextEditingController startTimepicker = TextEditingController();
TextEditingController endDatepicker = TextEditingController();
TextEditingController endTimepicker = TextEditingController();
final _stringTagController = StringTagController();
DateTime startDate = DateTime.now();
DateTime endDate = DateTime.now();
List<Map<String, dynamic>> suggestions = [];
String geographicalZone = "";
String imgUrl = "";
List<String> initialTags = [];
final _stringOrgaController = StringTagController();
List<String> initialOrga = [];
onTapFunctionDatePicker(
{required BuildContext context, required String position}) async {
DateTime date;
if ((startDatepicker.text.isEmpty) || (endDatepicker.text.isEmpty)) {
date = DateTime.now();
} else {
date = DateTime.parse(formatDate(startDatepicker.text));
if (position == "end") {
date = DateTime.parse(formatDate(endDatepicker.text));
}
}
DateTime? pickedDate = await showDatePicker(
context: context,
firstDate: date,
initialDate: date,
lastDate: DateTime(2104));
if (pickedDate == null) return;
if (position == "start") {
startDatepicker.text = DateFormat("dd/MM/yyyy").format(pickedDate);
}
if (position == "end") {
endDatepicker.text = DateFormat("dd/MM/yyyy").format(pickedDate);
}
}
onTapFunctionTimePicker(
{required BuildContext context, required String position}) async {
TimeOfDay time;
if ((startTimepicker.text.isEmpty) || (endTimepicker.text.isEmpty)) {
time = TimeOfDay.now();
} else {
DateTime date = new DateTime.now();
date = date.copyWith(
hour: int.parse(startTimepicker.text.split(":")[0]),
minute: int.parse(startTimepicker.text.split(":")[1]));
time = TimeOfDay.fromDateTime(date);
if (position == "end") {
date = date.copyWith(
hour: int.parse(endTimepicker.text.split(":")[0]),
minute: int.parse(endTimepicker.text.split(":")[1]));
time = TimeOfDay.fromDateTime(date);
}
}
TimeOfDay? pickedDate =
await showTimePicker(context: context, initialTime: time);
if (pickedDate == null) return;
if (position == "start") {
startTimepicker.text = pickedDate.format(context);
}
if (position == "end") {
endTimepicker.text = pickedDate.format(context);
}
}
convertNulltoEmptyString(var check) {
if (check == null) {
return "";
}
return check;
}
convertNulltoArray(List<String> check) {
if (check == null) {
return [];
}
return check;
}
String formatDate(String date) {
var splitedDate = date.split("/");
var day = splitedDate[0];
var month = splitedDate[1];
var year = splitedDate[2];
return "${year}-${month}-${day}";
}
Future<void> _updateEvent(BuildContext context) async {
if (!_isEventInFuture()) {
_showErrorDialog(
context,
AppLocalizations.of(context)?.error_event ?? "Event error",
AppLocalizations.of(context)?.no_future_event ?? "No future event");
return;
}
final accessToken = await _getAccessToken();
if (accessToken.isEmpty) {
_showErrorDialog(
context,
AppLocalizations.of(context)?.error_user ?? "User error",
AppLocalizations.of(context)?.empty_input ?? "Empty input");
return;
}
try {
await dotenv.load();
final geolocation = await _fetchGeolocation();
if (geolocation == null) {
_showErrorDialog(
context,
AppLocalizations.of(context)?.error ?? "Error",
AppLocalizations.of(context)?.no_data_geo ??
"No geographical data");
return;
}
if (await _isDuplicateEvent(accessToken, geolocation)) {
_showErrorDialog(
context,
AppLocalizations.of(context)?.info_event ?? "Event info",
AppLocalizations.of(context)?.event_already ??
"Event already exists");
return;
}
if (widget.imgPath.isNotEmpty) {
imgUrl = await _uploadImage(widget.imgPath);
if (imgUrl.isEmpty) {
_showErrorDialog(
context,
AppLocalizations.of(context)?.picture_error ?? "Error picture",
AppLocalizations.of(context)?.no_picture_published ??
"No picture published");
return;
}
}
await _updateEventData(accessToken, geolocation);
String message =
AppLocalizations.of(context)?.event_update ?? "Event updated";
showEventDialog(context, "${message} : ${inputName.text}");
} catch (e) {
_showErrorDialog(
context, AppLocalizations.of(context)?.error ?? "Error", "$e");
}
}
bool _isEventInFuture() {
DateTime startDateCompare = DateTime.parse(
"${formatDate(startDatepicker.text)}T${startTimepicker.text.replaceAll('-', ':')}");
return startDateCompare.isAfter(DateTime.now());
}
Future<String> _getAccessToken() async {
final prefs = await SharedPreferences.getInstance();
return prefs.getString("access_token") ?? "";
}
Future<Map<String, dynamic>?> _fetchGeolocation() async {
final apiKey = dotenv.env['PLACE_API_KEY'] ?? '';
final response = await http.get(Uri.parse(
'https://maps.googleapis.com/maps/api/place/textsearch/json?query=${inputGeo.text}&key=$apiKey'));
if (response.statusCode == 200) {
final data = json.decode(response.body);
if (data['results'].isNotEmpty) {
return data['results'][0]['geometry']['location'];
}
}
return null;
}
Future<bool> _isDuplicateEvent(
String accessToken, Map<String, dynamic> location) async {
final url = Uri.parse(
"${globals.api}/events/search?item=${inputName.text}&date_event=${formatDate(startDatepicker.text)}"
"&min_lat=${location['lat']}&max_lat=${location['lat']}"
"&min_lon=${location['lng']}&max_lon=${location['lng']}");
final response = await http.get(url,
headers: {HttpHeaders.cookieHeader: 'access_token=$accessToken'});
if (response.statusCode == 200) {
final events = jsonDecode(utf8.decode(response.bodyBytes));
return events.isNotEmpty && events[0]["id"] != widget.events!.id;
}
return false;
}
Future<String> _uploadImage(String imagePath) async {
final params = {
'expiration': '15552000',
'key': dotenv.env["IMGBB_API_KEY"]
};
final url = Uri.parse('https://api.imgbb.com/1/upload')
.replace(queryParameters: params);
final image = File(imagePath);
final req = http.MultipartRequest('POST', url)
..fields['image'] = base64.encode(await image.readAsBytes());
final response = await http.Response.fromStream(await req.send());
return response.statusCode == 200
? json.decode(response.body)["data"]["url"]
: "";
}
Future<void> _updateEventData(
String accessToken, Map<String, dynamic> location) async {
final url = Uri.parse("${globals.api}/events/${widget.events!.id}");
final response = await http.put(url,
headers: {
HttpHeaders.cookieHeader: 'access_token=$accessToken',
HttpHeaders.acceptHeader: 'application/json, text/plain, */*',
HttpHeaders.contentTypeHeader: 'application/json'
},
body: jsonEncode({
'name': inputName.text,
'place': inputGeo.text,
'start_date':
"${formatDate(startDatepicker.text)}T${startTimepicker.text.replaceAll('-', ':')}",
'end_date':
"${formatDate(endDatepicker.text)}T${endTimepicker.text.replaceAll('-', ':')}",
'organizers':
List<String>.from(_stringOrgaController.getTags as List),
'latitude': location['lat'],
'longitude': location['lng'],
'description': inputDesc.text,
"imgUrl": imgUrl,
'link': inputLink.text,
'ticket': inputTicket.text,
"tags": List<String>.from(_stringTagController.getTags as List)
}));
if (response.statusCode != 200 && response.statusCode != 201) {
_handleErrorResponse(context, response.statusCode);
}
}
void _handleErrorResponse(BuildContext context, int statusCode) {
final messages = {
400: AppLocalizations.of(context)?.request_error ??
"Poorly constructed query",
406: AppLocalizations.of(context)?.incorrect_password ??
"Incorrect password",
404: AppLocalizations.of(context)?.unknown_user ?? "Unknown user",
403: AppLocalizations.of(context)?.disabled_user ?? "Disabled user",
410: AppLocalizations.of(context)?.invalid_token ?? "Invalid token",
500: AppLocalizations.of(context)?.internal_error_server ??
"Internal error server"
};
_showErrorDialog(
context,
AppLocalizations.of(context)?.error ?? "Error",
messages[statusCode] ??
AppLocalizations.of(context)?.unknown_error_auth ??
"Unknown error auth");
}
void _showErrorDialog(BuildContext context, String title, String message) {
showAlertDialog(context, title, message);
}
@override
void initState() {
super.initState();
_authService.checkTokenStatus(context);
AdHelper.createBannerAd(() => setState(() {})).then((ad) {
setState(() {
_bannerAd = ad;
});
});
inputName.text = widget.events!.name ?? "";
inputTicket.text = widget.events!.ticket ?? "";
inputLink.text = widget.events!.link ?? "";
startDatepicker.text = DateFormat("dd/MM/yyyy")
.format(DateTime.parse(
widget.events!.startDate ?? DateTime.now().toString()))
.toString();
startTimepicker.text = DateFormat("HH:mm")
.format(DateTime.parse(
widget.events!.startDate ?? DateTime.now().toString()))
.toString();
endDatepicker.text = DateFormat("dd/MM/yyyy")
.format(
DateTime.parse(widget.events!.endDate ?? DateTime.now().toString()))
.toString();
endTimepicker.text = DateFormat("HH:mm")
.format(
DateTime.parse(widget.events!.endDate ?? DateTime.now().toString()))
.toString();
inputGeo.text = widget.events!.place ?? "";
imgUrl = widget.events!.imgUrl ?? "";
inputDesc.text = widget.events!.description ?? "";
initialTags = List<String>.from((widget.events?.tags as List?) ?? []);
initialOrga = List<String>.from((widget.events?.organizers as List?) ?? []);
}
final _formKey = GlobalKey<FormState>();
String? _validateField(String? value) {
return value!.isEmpty
? AppLocalizations.of(context)?.required_input ?? "Required input"
: null;
}
Future<void> searchSuggestions(String input) async {
await dotenv.load(fileName: ".env"); // Load .env file
final mapboxAccessToken = dotenv.env['MAPBOX_ACCESS_TOKEN'] ?? '';
final url =
'https://api.mapbox.com/geocoding/v5/mapbox.places/${input}.json?access_token=${mapboxAccessToken}&types=poi,address,place';
var encoded = Uri.encodeFull(url);
final response = await http.get(Uri.parse(encoded));
if (response.statusCode == 200) {
final data = json.decode(response.body);
setState(() {
suggestions = (data['features'] as List)
.map((feature) => {
'place_name': feature['place_name'],
'text': feature['text'],
'geometry': feature[
'geometry'], // Include geometry for latitude/longitude
})
.toList();
});
} else {
throw Exception('Failed to load suggestions');
}
}
Padding _buildGeographicalZoneSearchField() {
return Padding(
padding:
const EdgeInsets.only(left: 15.0, right: 15.0, top: 15, bottom: 0),
child: Column(
children: [
TextField(
controller: inputGeo,
decoration: InputDecoration(
labelText: AppLocalizations.of(context)?.location ?? "Location",
border: OutlineInputBorder(),
suffixIcon: IconButton(
icon: const Icon(Icons.clear),
onPressed: () {
setState(() {
inputGeo.clear(); // Clear the text field
geographicalZone = ''; // Reset the geographical zone state
suggestions.clear(); // Optionally clear suggestions
});
},
),
),
onChanged: (value) {
setState(() {
geographicalZone = value;
searchSuggestions(value);
});
},
),
if (suggestions.isNotEmpty)
Container(
height: 200,
decoration: BoxDecoration(
border: Border.all(color: Colors.blue),
borderRadius: BorderRadius.circular(8),
),
child: ListView.builder(
shrinkWrap: true,
itemCount: suggestions.length,
itemBuilder: (context, index) {
return ListTile(
title: Text(suggestions[index]['text']),
subtitle: Text(suggestions[index]['place_name']),
onTap: () async {
print("suggestion tapped : ${suggestions[index]}");
final latitude =
suggestions[index]['geometry']['coordinates'][1];
final longitude =
suggestions[index]['geometry']['coordinates'][0];
setState(() {
geographicalZone = suggestions[index]['text'];
inputGeo.text = geographicalZone;
suggestions.clear();
});
},
);
},
),
),
],
),
);
}
Future<void> popCamera() async {
await availableCameras().then((value) => Navigator.push(
context,
MaterialPageRoute(
builder: (_) =>
CameraEdit(camera: value.first, events: widget.events))));
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
drawer: MyDrawer(),
appBar: AppBar(
title: Text(AppLocalizations.of(context)?.add_event ??
"Add or Update a event"),
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
),
body: Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
_bannerAd == null
? SizedBox.shrink()
: SizedBox(
height: _bannerAd!.size.height.toDouble(),
width: _bannerAd!.size.width.toDouble(),
child: AdWidget(ad: _bannerAd!)),
if (widget.imgPath.isNotEmpty)
Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Center(
child: Container(
width: 200,
height: 150,
decoration: BoxDecoration(
borderRadius: BorderRadius.circular(100.0)),
child: Image.file(File(widget.imgPath))),
),
),
if (widget.imgPath.isEmpty)
Padding(
padding: const EdgeInsets.only(top: 60.0),
child: Image.network(
imgUrl,
width: MediaQuery.of(context).size.width *
0.5, // 50% of screen width
height: MediaQuery.of(context).size.height * 0.5,
loadingBuilder: (BuildContext context, Widget child,
ImageChunkEvent? loadingProgress) {
if (loadingProgress == null) {
return child; // The image has finished loading
}
return Center(
child: CircularProgressIndicator(),
);
},
errorBuilder: (BuildContext context, Object error,
StackTrace? stackTrace) {
return Center(
child: Icon(Icons.error,
size: MediaQuery.of(context).size.width * 0.1),
);
},
)),
Padding(
padding: EdgeInsets.symmetric(horizontal: 15),
child: ElevatedButton.icon(
onPressed: popCamera,
icon: Icon(Icons.edit, size: 16), // Edit icon
label: Text(AppLocalizations.of(context)?.edit_image ??
"Edit pictures"), // Button text
style: ElevatedButton.styleFrom(
backgroundColor: Colors.blue, // Button color
foregroundColor: Colors.white, // Text color
padding:
EdgeInsets.symmetric(horizontal: 10, vertical: 5),
),
),
),
Padding(
//padding: const EdgeInsets.only(left:15.0,right: 15.0,top:0,bottom: 0),
padding: EdgeInsets.symmetric(horizontal: 15),
child: TextFormField(
controller: inputName,
validator: (value) => _validateField(value),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: AppLocalizations.of(context)?.name ?? "Name",
hintText:
AppLocalizations.of(context)?.edit_event_name ??
"Edit event name"),
),
),
_buildGeographicalZoneSearchField(),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextFormField(
controller: startDatepicker,
readOnly: true,
validator: (value) => _validateField(value),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: AppLocalizations.of(context)?.start_date ??
"Start date",
hintText: AppLocalizations.of(context)?.select_date ??
"Click to select a date"),
onTap: () => onTapFunctionDatePicker(
context: context, position: "start")),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextFormField(
controller: startTimepicker,
readOnly: true,
validator: (value) => _validateField(value),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: AppLocalizations.of(context)?.start_time ??
"Start time",
hintText: AppLocalizations.of(context)?.select_time ??
"Click to select a time"),
onTap: () => onTapFunctionTimePicker(
context: context, position: "start")),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextFormField(
controller: endDatepicker,
readOnly: true,
validator: (value) => _validateField(value),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: AppLocalizations.of(context)?.end_date ??
"End date",
hintText: AppLocalizations.of(context)?.select_time ??
"Click to select a date"),
onTap: () => onTapFunctionDatePicker(
context: context, position: "end")),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextFormField(
controller: endTimepicker,
readOnly: true,
validator: (value) => _validateField(value),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: AppLocalizations.of(context)?.end_time ??
"End time",
hintText: AppLocalizations.of(context)?.select_time ??
"Click to select a time"),
onTap: () => onTapFunctionTimePicker(
context: context, position: "end")),
),
Padding(
//padding: const EdgeInsets.only(left:15.0,right: 15.0,top:0,bottom: 0),
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
child: TextFormField(
controller: inputLink,
validator: (value) => _validateField(value),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: AppLocalizations.of(context)?.link ?? "Link",
hintText: AppLocalizations.of(context)?.edit_link ??
"Edit link event"),
),
),
Padding(
//padding: const EdgeInsets.only(left:15.0,right: 15.0,top:0,bottom: 0),
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
child: TextFormField(
controller: inputTicket,
validator: (value) => _validateField(value),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText:
AppLocalizations.of(context)?.ticket ?? "Ticket",
hintText: AppLocalizations.of(context)?.edit_ticket ??
"Edit ticket link"),
),
),
TextFieldTags<String>(
textfieldTagsController: _stringTagController,
initialTags: initialTags,
textSeparators: const [' ', ','],
validator: (String tag) {
if (_stringTagController.getTags!.contains(tag)) {
return AppLocalizations.of(context)?.already_tag ??
"You have already entered this tag";
}
return null;
},
inputFieldBuilder: (context, inputFieldValues) {
return Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
child: TextField(
controller: inputFieldValues.textEditingController,
focusNode: inputFieldValues.focusNode,
onChanged: inputFieldValues.onTagChanged,
onSubmitted: inputFieldValues.onTagSubmitted,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText:
AppLocalizations.of(context)?.tag ?? 'Tags',
hintText: inputFieldValues.tags.isNotEmpty
? ''
: AppLocalizations.of(context)?.enter_tag ??
"Enter tag...",
errorText: inputFieldValues.error,
prefixIcon: inputFieldValues.tags.isNotEmpty
? SingleChildScrollView(
controller:
inputFieldValues.tagScrollController,
scrollDirection: Axis.vertical,
child: Padding(
padding: const EdgeInsets.only(
top: 8,
bottom: 8,
left: 8,
),
child: Wrap(
runSpacing: 4.0,
spacing: 4.0,
children: inputFieldValues.tags
.map((String tag) {
return Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(20.0),
),
color: Colors.blue,
),
margin:
const EdgeInsets.symmetric(
horizontal: 5.0),
padding:
const EdgeInsets.symmetric(
horizontal: 10.0,
vertical: 5.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
InkWell(
child: Text(
'$tag',
style: const TextStyle(
color: Colors.white),
),
onTap: () {
//print("$tag selected");
},
),
const SizedBox(width: 4.0),
InkWell(
child: const Icon(
Icons.cancel,
size: 14.0,
color: Color.fromARGB(
255, 233, 233, 233),
),
onTap: () {
inputFieldValues
.onTagRemoved(tag);
},
)
],
),
);
}).toList()),
),
)
: null,
),
),
);
}),
TextFieldTags<String>(
textfieldTagsController: _stringOrgaController,
initialTags: initialOrga,
textSeparators: const [','],
validator: (String tag) {
if (_stringOrgaController.getTags!.contains(tag)) {
return AppLocalizations.of(context)
?.already_organiser ??
"You have already entered this organizer";
}
return null;
},
inputFieldBuilder: (context, inputFieldValues) {
return Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
child: TextField(
controller: inputFieldValues.textEditingController,
focusNode: inputFieldValues.focusNode,
onChanged: inputFieldValues.onTagChanged,
onSubmitted: inputFieldValues.onTagSubmitted,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText:
AppLocalizations.of(context)?.organizer ??
"Organizer",
hintText: inputFieldValues.tags.isNotEmpty
? ''
: AppLocalizations.of(context)
?.enter_organizer ??
"Enter a organizer",
errorText: inputFieldValues.error,
prefixIcon: inputFieldValues.tags.isNotEmpty
? SingleChildScrollView(
controller:
inputFieldValues.tagScrollController,
scrollDirection: Axis.vertical,
child: Padding(
padding: const EdgeInsets.only(
top: 8,
bottom: 8,
left: 8,
),
child: Wrap(
runSpacing: 4.0,
spacing: 4.0,
children: inputFieldValues.tags
.map((String tag) {
return Container(
decoration: const BoxDecoration(
borderRadius: BorderRadius.all(
Radius.circular(20.0),
),
color: Colors.blue,
),
margin:
const EdgeInsets.symmetric(
horizontal: 5.0),
padding:
const EdgeInsets.symmetric(
horizontal: 10.0,
vertical: 5.0),
child: Row(
mainAxisAlignment:
MainAxisAlignment.start,
mainAxisSize: MainAxisSize.min,
children: [
InkWell(
child: Text(
'$tag',
style: const TextStyle(
color: Colors.white),
),
onTap: () {
//print("$tag selected");
},
),
const SizedBox(width: 4.0),
InkWell(
child: const Icon(
Icons.cancel,
size: 14.0,
color: Color.fromARGB(
255, 233, 233, 233),
),
onTap: () {
inputFieldValues
.onTagRemoved(tag);
},
)
],
),
);
}).toList()),
),
)
: null,
),
),
);
}),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextField(
controller: inputDesc,
keyboardType: TextInputType.multiline,
maxLines: 10,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: AppLocalizations.of(context)?.description ??
'Description',
hintText:
AppLocalizations.of(context)?.describe_event ??
'Describe event'),
),
),
SizedBox(
height: 30,
),
Container(
height: 50,
width: 250,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(20)),
child: TextButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
_updateEvent(context);
}
},
child: Text(
AppLocalizations.of(context)?.add ?? 'Add',
style: TextStyle(color: Colors.white, fontSize: 25),
),
),
)
],
),
),
));
}
}

View File

@@ -0,0 +1,396 @@
import 'package:covas_mobile/classes/MyDrawer.dart';
import 'package:flutter/material.dart';
import 'package:shared_preferences/shared_preferences.dart';
import 'package:http/http.dart' as http;
import 'package:intl/intl.dart';
import 'dart:convert';
import 'dart:io';
import '../classes/MyDrawer.dart';
import '../pages/LoginDemo.dart';
import '../classes/alert.dart';
import '../classes/eventAdded.dart';
import '../variable/globals.dart' as globals;
import '../classes/ad_helper.dart';
import 'package:google_mobile_ads/google_mobile_ads.dart';
import '../classes/auth_service.dart';
import 'package:flutter_localizations/flutter_localizations.dart';
import 'package:covas_mobile/gen_l10n/app_localizations.dart';
import 'package:provider/provider.dart';
import '../locale_provider.dart'; // Créé
void main() async {
WidgetsFlutterBinding.ensureInitialized();
await MobileAds.instance.initialize();
runApp(MyApp());
}
class MyApp extends StatelessWidget {
@override
Widget build(BuildContext context) {
return MaterialApp(
debugShowCheckedModeBanner: false,
home: EditProfile(),
);
}
}
class EditProfile extends StatefulWidget {
const EditProfile({super.key});
@override
_EditProfileState createState() => _EditProfileState();
}
class _EditProfileState extends State<EditProfile>
with ShowAlertDialog, ShowEventDialog {
BannerAd? _bannerAd;
final AuthService _authService = AuthService();
TextEditingController inputUserName = TextEditingController();
TextEditingController inputName = TextEditingController();
TextEditingController inputFirstName = TextEditingController();
TextEditingController inputEmail = TextEditingController();
TextEditingController inputBirth = TextEditingController();
TextEditingController inputPassword = TextEditingController();
TextEditingController inputPasswordConfirmed = TextEditingController();
onTapFunctionDatePicker({required BuildContext context}) async {
DateTime initialDate = DateTime.parse(formatDate(inputBirth.text));
DateTime? pickedDate = await showDatePicker(
context: context,
firstDate: DateTime(1900),
initialDate: initialDate,
lastDate: DateTime(2104));
if (pickedDate == null) return;
inputBirth.text = DateFormat("dd/MM/yyyy").format(pickedDate);
}
convertNulltoEmptyString(var check) {
if (check == null) {
return "";
}
return check;
}
convertNulltoArray(List<String> check) {
if (check == null) {
return [];
}
return check;
}
String formatDate(String date) {
var splitedDate = date.split("/");
var day = splitedDate[0];
var month = splitedDate[1];
var year = splitedDate[2];
return "${year}-${month}-${day}";
}
Future<void> _updateProfile(BuildContext context) async {
var username = inputUserName.text;
var firstName = inputFirstName.text;
var name = inputName.text;
var email = inputEmail.text;
var password = inputPassword.text;
var confirmedPassword = inputPasswordConfirmed.text;
var birth = DateTime.parse(formatDate(inputBirth.text));
if ((password.isNotEmpty) && (confirmedPassword.isNotEmpty)) {
if (password != confirmedPassword) {
showAlertDialog(
context,
AppLocalizations.of(context)?.error ?? "Error",
AppLocalizations.of(context)?.different_password_error ??
"Different password");
return;
}
}
var urlPut = Uri.parse("${globals.api}/users/me");
SharedPreferences prefs = await SharedPreferences.getInstance();
var accessToken = prefs.getString("access_token") ?? "";
if (accessToken.isNotEmpty) {
var responsePut = await http.put(urlPut,
headers: {
HttpHeaders.cookieHeader: 'access_token=${accessToken}',
HttpHeaders.acceptHeader: 'application/json, text/plain, */*',
HttpHeaders.contentTypeHeader: 'application/json'
},
body: jsonEncode({
'name': name,
'username': username,
'firstName': firstName,
'password': password,
'email': email,
'roles': '',
'birth': birth.toString()
}));
print(responsePut.statusCode);
if (responsePut.statusCode == 200) {
showEventDialog(context,
AppLocalizations.of(context)?.user_update ?? "Your user updated");
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (_) => EditProfile()));
return;
}
final messages = {
400: AppLocalizations.of(context)?.request_error ??
"Poorly constructed query",
406: AppLocalizations.of(context)?.incorrect_password ??
"Incorrect password",
404: AppLocalizations.of(context)?.unknown_user ?? "Unknown user",
403: AppLocalizations.of(context)?.disabled_user ?? "Disabled user",
410: AppLocalizations.of(context)?.invalid_token ?? "Invalid token",
500: AppLocalizations.of(context)?.internal_error_server ??
"Internal error server"
};
final text = messages[responsePut.statusCode] ??
AppLocalizations.of(context)?.unknown_error_auth ??
"Unknown error auth";
showAlertDialog(
context, AppLocalizations.of(context)?.error ?? "Error", text);
} else {
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (_) => LoginDemo()));
}
}
Future<void> _getInfoProfile() async {
var urlGet = Uri.parse("${globals.api}/users/me");
SharedPreferences prefs = await SharedPreferences.getInstance();
var accessToken = prefs.getString("access_token") ?? "";
if (accessToken.isNotEmpty) {
var responseGet = await http.get(urlGet, headers: {
HttpHeaders.cookieHeader: 'access_token=${accessToken}',
HttpHeaders.acceptHeader: 'application/json, text/plain, */*',
HttpHeaders.contentTypeHeader: 'application/json'
});
print(responseGet.statusCode);
if (responseGet.statusCode == 200) {
var body = json.decode(utf8.decode(responseGet.bodyBytes));
setState(() {
inputName.text = body["name"];
inputFirstName.text = body["firstName"];
inputUserName.text = body["username"];
inputEmail.text = body["email"];
inputBirth.text =
DateFormat("dd/MM/yyyy").format(DateTime.parse(body["birth"]));
});
return;
}
final messages = {
400: AppLocalizations.of(context)?.request_error ??
"Poorly constructed query",
406: AppLocalizations.of(context)?.incorrect_password ??
"Incorrect password",
404: AppLocalizations.of(context)?.unknown_user ?? "Unknown user",
403: AppLocalizations.of(context)?.disabled_user ?? "Disabled user",
410: AppLocalizations.of(context)?.invalid_token ?? "Invalid token",
500: AppLocalizations.of(context)?.internal_error_server ??
"Internal error server"
};
final text = messages[responseGet.statusCode] ??
AppLocalizations.of(context)?.unknown_error_auth ??
"Unknown error auth";
showAlertDialog(
context, AppLocalizations.of(context)?.error ?? "Error", text);
} else {
Navigator.pushReplacement(
context, MaterialPageRoute(builder: (_) => LoginDemo()));
}
}
@override
void initState() {
super.initState();
_authService.checkTokenStatus(context);
AdHelper.createBannerAd(() => setState(() {})).then((ad) {
setState(() {
_bannerAd = ad;
});
});
_getInfoProfile();
}
final _formKey = GlobalKey<FormState>();
String? _validateField(String? value) {
return value!.isEmpty
? AppLocalizations.of(context)?.required_input ?? "Required input"
: null;
}
@override
Widget build(BuildContext context) {
return Scaffold(
backgroundColor: Colors.white,
appBar: AppBar(
title: Text(
AppLocalizations.of(context)?.update_profile ?? "Update profile"),
backgroundColor: Colors.blue,
foregroundColor: Colors.white,
),
drawer: MyDrawer(),
body: Form(
key: _formKey,
child: SingleChildScrollView(
child: Column(
children: <Widget>[
_bannerAd == null
? SizedBox.shrink()
: SizedBox(
height: _bannerAd!.size.height.toDouble(),
width: _bannerAd!.size.width.toDouble(),
child: AdWidget(ad: _bannerAd!)),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextFormField(
controller: inputUserName,
validator: (value) => _validateField(value),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: AppLocalizations.of(context)?.name,
hintText: AppLocalizations.of(context)?.edit_pseudo ??
"Edit pseudo"),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextFormField(
controller: inputPassword,
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: AppLocalizations.of(context)?.password ??
"Password",
hintText:
AppLocalizations.of(context)?.enter_password ??
"Enter a password"),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextFormField(
controller: inputPasswordConfirmed,
obscureText: true,
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText:
AppLocalizations.of(context)?.password_confirmed ??
"Must confirm password",
hintText:
AppLocalizations.of(context)?.password_confirmed ??
"Must confirm password"),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextFormField(
controller: inputName,
validator: (value) => _validateField(value),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: AppLocalizations.of(context)?.last_name ??
"Last name",
hintText:
AppLocalizations.of(context)?.edit_last_name ??
"Edit last name"),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextFormField(
controller: inputFirstName,
validator: (value) => _validateField(value),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: AppLocalizations.of(context)?.first_name ??
"First name",
hintText:
AppLocalizations.of(context)?.edit_first_name ??
"Edit first name"),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextFormField(
controller: inputEmail,
validator: (value) => _validateField(value),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText:
AppLocalizations.of(context)?.email ?? "Email",
hintText: AppLocalizations.of(context)?.edit_email ??
"Edit email"),
),
),
Padding(
padding: const EdgeInsets.only(
left: 15.0, right: 15.0, top: 15, bottom: 0),
//padding: EdgeInsets.symmetric(horizontal: 15),
child: TextFormField(
controller: inputBirth,
readOnly: true,
validator: (value) => _validateField(value),
decoration: InputDecoration(
border: OutlineInputBorder(),
labelText: AppLocalizations.of(context)?.birth_date,
hintText: AppLocalizations.of(context)?.edit_birth ??
"Click to select a birth date"),
onTap: () => onTapFunctionDatePicker(context: context)),
),
SizedBox(
height: 30,
),
Container(
height: 50,
width: 250,
decoration: BoxDecoration(
color: Colors.blue,
borderRadius: BorderRadius.circular(20)),
child: TextButton(
onPressed: () {
if (_formKey.currentState!.validate()) {
_updateProfile(context);
}
},
child: Text(
AppLocalizations.of(context)?.update_profile ??
"Update profile ",
style: TextStyle(color: Colors.white, fontSize: 25),
),
),
)
],
),
),
));
}
}

Some files were not shown because too many files have changed in this diff Show More