branch feature/28_avatars updated (a04e635a -> 350108b4)
This is an automated email from the git hooks/post-receive script. New change to branch feature/28_avatars in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git omits a04e635a refs #28 forumlaire d'upload de l'avatar omits f0692bd5 refs #28 finalement on stocke l'avatar dans une resource en base meme quand ça vient d'un tiers omits 95718ac2 refs #28 message si avatar non chargé omits c7550c51 refs #28 ajout de l'avatar pour l'utilisateur + possibilité d'en choisir un parmi les providers disponibles adds aa1b84a5 Correction affichage votes anoymes adds 053f9ed8 fixes #146 The registration form does not display on mobiles adds a1227dbd logout en delete et oubli de mot de passe en post adds 80d82627 Corretion de la methode pour les votes alternatifs adds 9913fcb0 update gitlab ci for release adds d9f7d087 update gitlab ci for release adds 9366dcba update gitlab ci for release adds 26842f63 update gitlab ci for release adds 92897a30 update gitlab ci for release adds edaa1be6 fixes #150 bouchage des trous de secu adds 72199763 Maj des dépendances et entêtes en vue de la release. adds 66b90103 update gitlab ci for release adds 02a5af9d ajout de l'url de voe à partager dans la page de résumé du sondage + warning pour ne pas partager la page de résumé adds 6e45bf56 ajout d'un tooltip sur le bouton copier + suppression du warning adds 863823eb style adds 791e3415 update gitlab ci for release adds d8b73ea2 update gitlab ci for release adds 846d7878 update gitlab ci for release adds 7c572986 update gitlab ci for release adds 037a7157 update gitlab ci for release adds 3fe11b0b update gitlab ci for release adds fb0d5b02 update gitlab ci for release adds 29e6854a update gitlab ci for release adds 57cf8c08 update gitlab ci for release adds cc88f3f3 Update .gitlab-ci.yml adds a954f3f5 Update .gitlab-ci.yml adds c9a24a48 release 3.0.0 success [skip ci] adds 3afb5b13 release 3.0.0 success [skip ci] adds 66af7606 Update .gitlab-ci.yml adds 628af107 release 3.0.0 success [skip ci] adds 7ce8b58d Update .gitlab-ci.yml adds 9f9d925f suppression d'un mauvais nom de domaine adds 4ed8e91e Empty CHANGELOG adds 3b0a0e98 release 3.0.0 success [skip ci] adds bd177f18 Update .gitlab-ci.yml adds 34698a83 Update CHANGELOG adds f5608178 release 3.0.0 success [skip ci] adds bdf3b65c Merge branch 'release/3.0.0' adds 50cd29bb Merge tag '3.0.0' into develop new 13096a6c refs #28 ajout de l'avatar pour l'utilisateur + possibilité d'en choisir un parmi les providers disponibles new 7d02cf80 refs #28 message si avatar non chargé new 8c8503c4 refs #28 finalement on stocke l'avatar dans une resource en base meme quand ça vient d'un tiers new c0153a85 refs #28 forumlaire d'upload de l'avatar new a9ba220a refs #28 utilisation de l'avatar new 350108b4 ajout e variable dans le package.json This update added new revisions after undoing existing revisions. That is to say, some revisions that were in the old version of the branch are not in the new version. This situation occurs when a user --force pushes a change and generates a repository containing something like this: * -- * -- B -- O -- O -- O (a04e635a) \ N -- N -- N refs/heads/feature/28_avatars (350108b4) You should already have received notification emails for all of the O revisions, and so the following emails describe only the N revisions from the common base, B. Any revisions marked "omits" are not gone; other references still refer to them. Any revisions marked "discards" are gone forever. The 6 revisions listed above as "new" are entirely new to this repository and will be described in separate emails. The revisions listed as "adds" were already present in the repository and have only been added to this reference. Detailed log of new commits: commit 350108b48a96f0a707008da0f8d2d78aa21aaf9c Author: Kevin Morin <morin@codelutin.com> Date: Fri Sep 29 10:02:28 2017 +0200 ajout e variable dans le package.json commit a9ba220a76c759a9daf6527930fb88fb6156245d Author: Kevin Morin <morin@codelutin.com> Date: Thu Sep 28 11:12:43 2017 +0200 refs #28 utilisation de l'avatar commit c0153a8599aeab4c0b35f79cc3f449fdc978a26e Author: Kevin Morin <morin@codelutin.com> Date: Tue Sep 26 10:55:28 2017 +0200 refs #28 forumlaire d'upload de l'avatar commit 8c8503c4e5c11165e7efbddf4a9991f12d788d39 Author: Kevin Morin <morin@codelutin.com> Date: Fri Sep 22 17:42:51 2017 +0200 refs #28 finalement on stocke l'avatar dans une resource en base meme quand ça vient d'un tiers commit 7d02cf80f1d8d04bb993e4931c9e38516db75189 Author: Kevin Morin <morin@codelutin.com> Date: Fri Sep 22 10:39:10 2017 +0200 refs #28 message si avatar non chargé commit 13096a6c8b30e8effc6f070c3776b0ab430bb917 Author: Kevin Morin <morin@codelutin.com> Date: Tue Sep 19 18:10:32 2017 +0200 refs #28 ajout de l'avatar pour l'utilisateur + possibilité d'en choisir un parmi les providers disponibles Summary of changes: .gitlab-ci.yml | 73 ++++++++++++++++++ CHANGELOG | 23 ++++++ pollen-persistence/pom.xml | 2 +- .../org/chorem/pollen/persistence/DaoUtils.java | 21 ++++++ .../persistence/PollenFlywayServiceImpl.java | 21 ++++++ .../entity/ChildFavoriteListTopiaDao.java | 23 +++++- .../entity/FavoriteListMemberTopiaDao.java | 21 ++++++ .../pollen/persistence/entity/PollenUserImpl.java | 21 ++++++ .../pollen/persistence/entity/ReportResume.java | 21 ++++++ .../pollen/persistence/entity/ReportTopiaDao.java | 21 ++++++ .../persistence/entity/UserCredentialTopiaDao.java | 27 ++++++- .../entity/VoterListMemberTopiaDao.java | 21 ++++++ pollen-rest-api/pom.xml | 7 +- pollen-rest-api/src/license/THIRD-PARTY.properties | 28 ++++--- .../pollen/rest/api/PollenRestApiApplication.java | 21 ++++++ .../pollen/rest/api/beans/ChangePasswordBean.java | 23 +++++- .../pollen/rest/api/beans/PollCreateBean.java | 21 ++++++ .../pollen/rest/api/beans/Resource64Bean.java | 21 ++++++ .../pollen/rest/api/beans/VoterListSaveBean.java | 21 ++++++ .../pollen/rest/api/converter/JacksonConfig.java | 21 ++++++ .../api/converter/PollenConverterProvider.java | 21 ++++++ .../api/converter/PollenEntityIdDeserializer.java | 21 ++++++ .../api/converter/PollenEntityIdSerializer.java | 21 ++++++ .../api/converter/PollenEntityRefDeserializer.java | 21 ++++++ .../api/converter/PollenEntityRefSerializer.java | 21 ++++++ .../FavoriteListImportExceptionMapper.java | 21 ++++++ .../InvalidEntityLinkExceptionMapper.java | 21 ++++++ .../InvalidFormExceptionMapper.java | 21 ++++++ .../PollenAbstractExceptionMapper.java | 21 ++++++ .../PollenAuthenticationExceptionMapper.java | 21 ++++++ .../PollenEmailNotValidatedExceptionMapper.java | 21 ++++++ ...rProviderAccountAlreadyUsedExceptionMapper.java | 21 ++++++ ...InvalidEmailActivationTokenExceptionMapper.java | 21 ++++++ .../PollenInvalidPermissionExceptionMapper.java | 21 ++++++ .../PollenInvalidSessionTokenExceptionMapper.java | 21 ++++++ .../PollenUnauthorizedExceptionMapper.java | 21 ++++++ .../PollenUserBannedExceptionMapper.java | 21 ++++++ .../TopiaNoResultExceptionMapper.java | 21 ++++++ .../org/chorem/pollen/rest/api/v1/ApiUtils.java | 21 ++++++ .../org/chorem/pollen/rest/api/v1/AuthApi.java | 8 +- .../org/chorem/pollen/rest/api/v1/FeedbackApi.java | 21 ++++++ .../java/org/chorem/pollen/rest/api/v1/GtuApi.java | 21 ++++++ .../pollen/rest/api/v1/PollenResourceApi.java | 15 ---- .../chorem/pollen/rest/api/v1/PollenUserApi.java | 3 +- .../chorem/pollen/rest/api/v1/VoterListApi.java | 13 ---- .../org/chorem/pollen/rest/api/AuthApiTest.java | 2 +- pollen-services/pom.xml | 2 +- .../chorem/pollen/services/PollenUIContext.java | 21 ++++++ .../java/org/chorem/pollen/services/UnitHuman.java | 21 ++++++ .../services/bean/ChildFavoriteListBean.java | 21 ++++++ .../chorem/pollen/services/bean/FeedbackBean.java | 21 ++++++ .../pollen/services/bean/LoginProviderBean.java | 21 ++++++ .../org/chorem/pollen/services/bean/PollBean.java | 13 ++++ .../chorem/pollen/services/bean/ReportBean.java | 21 ++++++ .../chorem/pollen/services/bean/ReportLevel.java | 21 ++++++ .../pollen/services/bean/ReportResumeBean.java | 21 ++++++ .../pollen/services/bean/UserCredentialBean.java | 21 ++++++ .../bean/export/ChildFavoriteListExport.java | 21 ++++++ .../pollen/services/bean/export/ExportBean.java | 21 ++++++ .../services/bean/export/FavoriteListsExport.java | 21 ++++++ .../pollen/services/bean/resource/GtuMetaBean.java | 21 ++++++ .../services/bean/resource/ResourceMetaBean.java | 2 +- .../Coombs/CoombsDetailResultBean.java | 21 ++++++ .../bean/voteCounting/Coombs/CoombsRoundBean.java | 21 ++++++ .../voteCounting/Coombs/CoombsRoundChoiceBean.java | 21 ++++++ .../InstantRunoffDetailResultBean.java | 21 ++++++ .../InstantRunoff/InstantRunoffRoundBean.java | 21 ++++++ .../InstantRunoffRoundChoiceBean.java | 21 ++++++ .../voteCounting/VoteCountingDetailResultBean.java | 21 ++++++ .../voteCounting/borda/BordaChoiceRankBean.java | 21 ++++++ .../voteCounting/borda/BordaDetailResultBean.java | 21 ++++++ .../condorcet/CondorcetBattleBean.java | 21 ++++++ .../condorcet/CondorcetDetailResultBean.java | 21 ++++++ .../pollen/services/job/AbstractPollenJob.java | 21 ++++++ .../pollen/services/job/SendEmailInErrorsJob.java | 21 ++++++ .../services/job/SendPollEndReminderJob.java | 21 ++++++ .../pollen/services/service/ChoiceService.java | 1 + .../services/service/FavoriteListService.java | 77 +++++++------------ .../pollen/services/service/FeedService.java | 21 ++++++ .../pollen/services/service/FeedbackService.java | 21 ++++++ .../chorem/pollen/services/service/GtuService.java | 28 ++++++- .../pollen/services/service/PollService.java | 20 ++--- .../services/service/PollenResourceService.java | 19 +---- .../services/service/PollenServiceSupport.java | 5 ++ .../pollen/services/service/PollenUserService.java | 22 +++--- .../pollen/services/service/ReportService.java | 21 ++++++ .../pollen/services/service/SocialAuthService.java | 33 ++++++-- .../services/service/VoteCountingService.java | 1 + .../services/service/mail/AbstractReportEmail.java | 21 ++++++ .../service/mail/AbstractReportForAdminEmail.java | 21 ++++++ .../services/service/mail/ChoiceReportEmail.java | 21 ++++++ .../service/mail/ChoiceReportForAdminEmail.java | 21 ++++++ .../services/service/mail/CommentReportEmail.java | 21 ++++++ .../service/mail/CommentReportForAdminEmail.java | 21 ++++++ .../services/service/mail/FeedbackEmail.java | 21 ++++++ .../services/service/mail/PollReportEmail.java | 21 ++++++ .../service/mail/PollReportForAdminEmail.java | 21 ++++++ ...EmailOrProviderAccountAlreadyUsedException.java | 21 ++++++ .../src/main/resources/oauth_consumer.properties | 22 +++++- .../pollen/services/service/PollServiceTest.java | 2 +- pollen-ui-riot-js/package.json | 2 +- .../jetty-context.xml => pollen-ui-riot-js/pom.xml | 23 ++++-- pollen-ui-riot-js/src/main/web/conf.js | 20 +++++ pollen-ui-riot-js/src/main/web/css/blaze.css | 20 +++++ .../src/main/web/css/custom-code-lutin.css | 20 +++++ pollen-ui-riot-js/src/main/web/css/custom.css | 20 +++++ pollen-ui-riot-js/src/main/web/css/main.css | 1 + pollen-ui-riot-js/src/main/web/css/print.css | 22 +++++- .../src/main/web/help/voteCountingTypes-en.html | 22 +++++- .../src/main/web/help/voteCountingTypes-fr.html | 22 +++++- pollen-ui-riot-js/src/main/web/home/en.html | 22 +++++- pollen-ui-riot-js/src/main/web/home/fr.html | 22 +++++- pollen-ui-riot-js/src/main/web/home/style.css | 22 +++++- pollen-ui-riot-js/src/main/web/homeCL/en.html | 22 +++++- pollen-ui-riot-js/src/main/web/homeCL/fr.html | 22 +++++- pollen-ui-riot-js/src/main/web/homeCL/offers.html | 22 +++++- pollen-ui-riot-js/src/main/web/homeCL/style.css | 22 +++++- pollen-ui-riot-js/src/main/web/i18n/en.json | 2 + pollen-ui-riot-js/src/main/web/i18n/fr.json | 2 + pollen-ui-riot-js/src/main/web/js/AuthService.js | 4 +- pollen-ui-riot-js/src/main/web/js/Logger.js | 20 +++++ pollen-ui-riot-js/src/main/web/js/PageTracker.js | 20 +++++ pollen-ui-riot-js/src/main/web/js/Pagination.js | 20 +++++ pollen-ui-riot-js/src/main/web/js/Poll.js | 20 +++++ pollen-ui-riot-js/src/main/web/js/PollenBus.js | 20 +++++ .../src/main/web/js/ResourceService.js | 4 + pollen-ui-riot-js/src/main/web/js/UIHelper.js | 20 +++++ pollen-ui-riot-js/src/main/web/js/UserService.js | 2 +- .../src/main/web/js/VoterListService.js | 20 +++++ .../src/main/web/tag/HeaderI18n.tag.html | 36 ++++----- pollen-ui-riot-js/src/main/web/tag/Home.tag.html | 36 ++++----- .../src/main/web/tag/Pagination.tag.html | 20 +++++ pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html | 48 +++++++----- .../src/main/web/tag/PollenFooter.tag.html | 36 ++++----- .../src/main/web/tag/PollenHeader.tag.html | 40 +++++----- .../src/main/web/tag/PollenMessageManager.tag.html | 20 +++++ .../src/main/web/tag/PollenWaiter.tag.html | 20 +++++ .../src/main/web/tag/Privacy.tag.html | 20 +++++ pollen-ui-riot-js/src/main/web/tag/QrCode.tag.html | 20 +++++ .../src/main/web/tag/SignCheck.tag.html | 36 ++++----- pollen-ui-riot-js/src/main/web/tag/SignIn.tag.html | 40 +++++----- pollen-ui-riot-js/src/main/web/tag/SignUp.tag.html | 43 ++++++----- .../src/main/web/tag/UserProfile.tag.html | 38 ++++++++-- .../src/main/web/tag/admin/GtuCard.tag.html | 20 +++++ .../src/main/web/tag/admin/Gtus.tag.html | 20 +++++ .../src/main/web/tag/admin/LoginProviders.tag.html | 20 +++++ .../src/main/web/tag/admin/UserCard.tag.html | 20 +++++ .../src/main/web/tag/admin/UserEditModal.tag.html | 20 +++++ .../src/main/web/tag/admin/Users.tag.html | 20 +++++ .../src/main/web/tag/components/Avatar.tag.html | 36 +++++++++ .../src/main/web/tag/components/Card.tag.html | 20 +++++ .../src/main/web/tag/components/Checkbox.tag.html | 22 +++++- .../web/tag/components/ContextualMenu.tag.html | 20 +++++ .../main/web/tag/components/GtuValidation.tag.html | 20 +++++ .../main/web/tag/components/HumanInput.tag.html | 20 +++++ .../src/main/web/tag/components/LazyLoad.tag.html | 20 +++++ .../main/web/tag/components/LetterAvatar.tag.html | 20 +++++ .../main/web/tag/components/LoadingCard.tag.html | 20 +++++ .../web/tag/components/MultiLineLabel.tag.html | 22 +++++- .../src/main/web/tag/components/Search.tag.html | 20 +++++ .../main/web/tag/components/date-picker.tag.html | 20 +++++ .../web/tag/components/date-time-picker.tag.html | 20 +++++ .../main/web/tag/components/time-picker.tag.html | 20 +++++ .../web/tag/favoriteList/ChildListCard.tag.html | 20 +++++ .../tag/favoriteList/ChildListEditModal.tag.html | 20 +++++ .../web/tag/favoriteList/FavoriteList.tag.html | 22 +++++- .../web/tag/favoriteList/FavoriteListCard.tag.html | 20 +++++ .../favoriteList/FavoriteListEditModal.tag.html | 20 +++++ .../web/tag/favoriteList/FavoriteLists.tag.html | 20 +++++ .../web/tag/favoriteList/ImportCsvModal.tag.html | 20 +++++ .../web/tag/favoriteList/ImportLdapModal.tag.html | 20 +++++ .../main/web/tag/favoriteList/MemberCard.tag.html | 20 +++++ .../web/tag/favoriteList/MemberEditModal.tag.html | 20 +++++ .../src/main/web/tag/poll/Choice.tag.html | 23 +++++- .../src/main/web/tag/poll/ChoiceView.tag.html | 26 ++++++- .../src/main/web/tag/poll/Choices.tag.html | 20 +++++ .../src/main/web/tag/poll/Comments.tag.html | 20 +++++ .../src/main/web/tag/poll/Description.tag.html | 36 ++++----- .../src/main/web/tag/poll/EditPoll.tag.html | 36 ++++----- .../src/main/web/tag/poll/Podium.tag.html | 20 +++++ .../src/main/web/tag/poll/Poll.tag.html | 20 +++++ .../src/main/web/tag/poll/PollCard.tag.html | 23 +++++- .../src/main/web/tag/poll/Polls.tag.html | 20 +++++ .../src/main/web/tag/poll/Report.tag.html | 20 +++++ .../src/main/web/tag/poll/Results.tag.html | 20 +++++ .../src/main/web/tag/poll/Settings.tag.html | 36 ++++----- .../src/main/web/tag/poll/Summary.tag.html | 78 ++++++++++++++++--- .../src/main/web/tag/poll/Votes.tag.html | 25 +++++- .../src/main/web/tag/popup/ConfirmPopup.tag.html | 20 +++++ .../src/main/web/tag/popup/FeedbackModal.tag.html | 20 +++++ .../src/main/web/tag/popup/GtuChangeModal.tag.html | 36 ++++----- .../main/web/tag/popup/InformationPopup.tag.html | 20 +++++ .../src/main/web/tag/popup/Modal.tag.html | 20 +++++ .../src/main/web/tag/popup/NewPassword.tag.html | 36 ++++----- .../src/main/web/tag/popup/QrCodeButton.tag.html | 20 +++++ .../main/web/tag/popup/ResendValidation.tag.html | 36 ++++----- .../voteCountingType/BordaDetailResult.tag.html | 20 +++++ .../CondorcetDetailResult.tag.html | 20 +++++ .../voteCountingType/CoombsDetailResult.tag.html | 20 +++++ .../InstantRunoffDetailResult.tag.html | 20 +++++ .../tag/voterList/ImportFavoritListModal.tag.html | 20 +++++ .../src/main/web/tag/voterList/VoterList.tag.html | 20 +++++ .../main/web/tag/voterList/VoterListCard.tag.html | 20 +++++ .../web/tag/voterList/VoterListEditModal.tag.html | 20 +++++ .../web/tag/voterList/VoterListMemberCard.tag.html | 20 +++++ .../voterList/VoterListMemberEditModal.tag.html | 20 +++++ pollen-ui-riot-js/webpack.config.js | 2 +- pollen-votecounting-aggregator/pom.xml | 2 +- pollen-votecounting-api/pom.xml | 2 +- .../model/VoteCountingDetailResult.java | 21 ++++++ pollen-votecounting-borda/pom.xml | 2 +- .../pollen/votecounting/BordaChoiceRank.java | 21 ++++++ .../pollen/votecounting/BordaDetailResult.java | 21 ++++++ pollen-votecounting-condorcet/pom.xml | 2 +- .../pollen/votecounting/CondorcetBattle.java | 21 ++++++ .../pollen/votecounting/CondorcetDetailResult.java | 21 ++++++ pollen-votecounting-coombs/pom.xml | 2 +- .../pollen/votecounting/CoombsDetailResult.java | 21 ++++++ .../chorem/pollen/votecounting/CoombsRound.java | 21 ++++++ .../pollen/votecounting/CoombsRoundChoice.java | 21 ++++++ pollen-votecounting-instant-runoff/pom.xml | 2 +- .../votecounting/InstantRunoffDetailResult.java | 21 ++++++ .../pollen/votecounting/InstantRunoffRound.java | 21 ++++++ .../votecounting/InstantRunoffRoundChoice.java | 21 ++++++ .../InstantRunoffVoteCountingStrategy.java | 6 +- .../InstantRunoffVoteCountingStrategyTest.java | 29 ++++--- pollen-votecounting-normal/pom.xml | 2 +- pollen-votecounting-number/pom.xml | 2 +- pollen-votecounting-percentage/pom.xml | 2 +- pom.xml | 88 +++++++++++++++------- 230 files changed, 4283 insertions(+), 504 deletions(-) create mode 100644 CHANGELOG copy pollen-rest-api/src/jetty/jetty-context.xml => pollen-ui-riot-js/pom.xml (58%) create mode 100644 pollen-ui-riot-js/src/main/web/tag/components/Avatar.tag.html -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/28_avatars in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 13096a6c8b30e8effc6f070c3776b0ab430bb917 Author: Kevin Morin <morin@codelutin.com> Date: Tue Sep 19 18:10:32 2017 +0200 refs #28 ajout de l'avatar pour l'utilisateur + possibilité d'en choisir un parmi les providers disponibles --- .../db/migration/h2/V3_0_0_11__add_avatar.sql | 2 ++ .../migration/postgresql/V3_0_0_11__add_avatar.sql | 2 ++ pollen-persistence/src/main/xmi/pollen.properties | 2 +- pollen-persistence/src/main/xmi/pollen.zargo | Bin 28355 -> 28419 bytes .../chorem/pollen/rest/api/v1/PollenUserApi.java | 17 +++++++++++++ .../pollen/services/bean/PollenUserBean.java | 12 +++++++++ .../pollen/services/service/SocialAuthService.java | 18 +++++++++++++ pollen-ui-riot-js/src/main/web/js/UserService.js | 6 +++++ pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html | 28 +++++++++++++++++++-- .../src/main/web/tag/UserProfile.tag.html | 24 ++++++++++++++++++ 10 files changed, 108 insertions(+), 3 deletions(-) diff --git a/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_11__add_avatar.sql b/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_11__add_avatar.sql new file mode 100644 index 00000000..197b01b4 --- /dev/null +++ b/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_11__add_avatar.sql @@ -0,0 +1,2 @@ +-- add user's avatar +alter table pollenUser add avatar VARCHAR(255); diff --git a/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_11__add_avatar.sql b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_11__add_avatar.sql new file mode 100644 index 00000000..197b01b4 --- /dev/null +++ b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_11__add_avatar.sql @@ -0,0 +1,2 @@ +-- add user's avatar +alter table pollenUser add avatar VARCHAR(255); diff --git a/pollen-persistence/src/main/xmi/pollen.properties b/pollen-persistence/src/main/xmi/pollen.properties index 926a53e6..19fe27c2 100644 --- a/pollen-persistence/src/main/xmi/pollen.properties +++ b/pollen-persistence/src/main/xmi/pollen.properties @@ -18,7 +18,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # #L% ###m -model.tagvalue.version=3.0.0.10 +model.tagvalue.version=3.0.0.11 #model.tagValue.notGenerateToString=true #model.tagValue.constantPrefix=PROPERTY_ #model.tagValue.useEnumerationName=true diff --git a/pollen-persistence/src/main/xmi/pollen.zargo b/pollen-persistence/src/main/xmi/pollen.zargo index 0da955ef..1642eec1 100644 Binary files a/pollen-persistence/src/main/xmi/pollen.zargo and b/pollen-persistence/src/main/xmi/pollen.zargo differ diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java index 130a8212..0968efa3 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java @@ -155,4 +155,21 @@ public class PollenUserApi { socialAuthService.deleteUserCredential(credentialId); } + + @Path("/users/{userId}/avatar/{provider}") + @POST + public String setAvatar(@Context SocialAuthService socialAuthService, + @Context HttpServletRequest request, + @PathParam("userId") PollenEntityId<PollenUser> userId, + @PathParam("provider") String provider, + String providerReturn) throws Exception { + + SocialAuthManager socialAuthManager = + (SocialAuthManager) request.getSession().getAttribute(ApiUtils.SOCIAL_AUTH_MANAGER_SESSION_KEY); + //socialAuthManager + request.getSession().removeAttribute(ApiUtils.SOCIAL_AUTH_MANAGER_SESSION_KEY); + Gson gson = new Gson(); + Map<String, String> paramsMap = gson.fromJson(providerReturn, Map.class); + return socialAuthService.setAvatarToUser(userId, socialAuthManager, paramsMap); + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenUserBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenUserBean.java index d1d1ccb5..aea1b1d0 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenUserBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenUserBean.java @@ -56,6 +56,8 @@ public class PollenUserBean extends PollenBean<PollenUser> { protected boolean gtuValidated; + protected String avatar; + public PollenUserBean() { super(PollenUser.class); } @@ -82,6 +84,7 @@ public class PollenUserBean extends PollenBean<PollenUser> { }) .collect(Collectors.toList())); } + setAvatar(entity.getAvatar()); } @Override @@ -95,6 +98,7 @@ public class PollenUserBean extends PollenBean<PollenUser> { entity.setLanguage(getLanguage()); entity.setEmail(getEmail()); entity.setPassword(getPassword()); + entity.setAvatar(getAvatar()); return entity; @@ -179,4 +183,12 @@ public class PollenUserBean extends PollenBean<PollenUser> { public void setGtuValidated(boolean gtuValidated) { this.gtuValidated = gtuValidated; } + + public String getAvatar() { + return avatar; + } + + public void setAvatar(String avatar) { + this.avatar = avatar; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java index 6997c249..4557276a 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java @@ -256,4 +256,22 @@ public class SocialAuthService extends PollenServiceSupport { getUserCredentialDao().delete(credential); commit(); } + + public String setAvatarToUser(PollenEntityId<PollenUser> userId, SocialAuthManager manager, Map<String, String> paramsMap) throws Exception { + checkIsConnected(); + PollenUser connectedUser = getConnectedUser(); + if (!connectedUser.getTopiaId().equals(userId.getEntityId())) { + throw new PollenUnauthorizedException(userId.getReducedId()); + } + + AuthProvider provider = manager.connect(paramsMap); + + // get profile + Profile p = provider.getUserProfile(); + + connectedUser.setAvatar(p.getProfileImageURL()); + commit(); + + return connectedUser.getAvatar(); + } } diff --git a/pollen-ui-riot-js/src/main/web/js/UserService.js b/pollen-ui-riot-js/src/main/web/js/UserService.js index c203638a..d1cceefa 100644 --- a/pollen-ui-riot-js/src/main/web/js/UserService.js +++ b/pollen-ui-riot-js/src/main/web/js/UserService.js @@ -81,6 +81,12 @@ class UserService extends FetchService { let url = "/v1/gtu/validate"; return this.post(url); } + + getProviderAvatar(userId, query) { + let url = this._getUrlPrefix(userId) + "/avatar/" + query.loginProvider; + let body = JSON.stringify(query); + return this.post(url, body); + } } module.exports = singleton(UserService); diff --git a/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html b/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html index 7b29d834..ef16fc1b 100644 --- a/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html @@ -236,8 +236,12 @@ require("./popup/GtuChangeModal.tag.html"); }); route("/user/profile", () => { - this.bus.trigger("pageChanged", "userProfile"); - riot.mount(this.refs.content, "userprofile"); + if (!session.isConnected()) { + route("/signin?url=/user/profile"); + } else { + this.bus.trigger("pageChanged", "userProfile"); + riot.mount(this.refs.content, "userprofile"); + } }); route("/favoriteLists", () => { this.bus.trigger("pageChanged", "favoriteLists"); @@ -301,6 +305,26 @@ require("./popup/GtuChangeModal.tag.html"); this.bus.off("user", callback); }); } + + } else if (q.action === "avatar" && session.isConnected()) { + let callback = (user) => { + userService.getProviderAvatar(user.id, q).then(() => { + location.replace(session.pollenUIContext.uiEndPoint + "/#user/profile"); + }, (e) => { + e.text().then(label => { + location.replace(session.pollenUIContext.uiEndPoint + "/#user/profile?error=" + label); + }); + }); + }; + + if (session.getUser()) { + callback(session.getUser()); + } else { + this.bus.on("user", (user) => { + callback(user); + this.bus.off("user", callback); + }); + } } } else { diff --git a/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html b/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html index 19f5f9c5..57fd0a0b 100644 --- a/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html @@ -164,6 +164,18 @@ require("./components/HumanInput.tag.html"); </a> </p> </div> + + <div class="o-form-element align-center" if="{loginProviders.length > 0}"> + <p>Avatar</p> + <p><img src="{user.avatar}" onerror="{test}"/></p> + <p> + <a each="{loginProvider in loginProviders}" class="provider-link" + onclick="{getProviderAvatar(loginProvider)}"> + <i class="fa fa-{authService.providerIcons[loginProvider]}" if="{authService.providerIcons[loginProvider]}"></i> + <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> + </a> + </p> + </div> </div> </div> @@ -190,6 +202,10 @@ require("./components/HumanInput.tag.html"); this.update(); }; +this.test = (e) => { +console.log(e) +} + this.resendValidation = () => { this.authService.resendValidation(this.user.email); }; @@ -263,6 +279,14 @@ require("./components/HumanInput.tag.html"); }); }; + getProviderAvatar= (provider) => (e) => { + let redirection = encodeURIComponent(location.origin + location.pathname + + "?loginProvider=" + provider + "&action=avatar"); + this.authService.getLoginProviderUrl(provider, redirection).then(result => { + location.assign(result); + }); + }; + this.listen("user", this.onUserChange); </script> -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/28_avatars in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 7d02cf80f1d8d04bb993e4931c9e38516db75189 Author: Kevin Morin <morin@codelutin.com> Date: Fri Sep 22 10:39:10 2017 +0200 refs #28 message si avatar non chargé --- .../org/chorem/pollen/rest/api/v1/AuthApi.java | 1 + pollen-ui-riot-js/src/main/web/i18n/en.json | 2 + pollen-ui-riot-js/src/main/web/i18n/fr.json | 2 + pollen-ui-riot-js/src/main/web/tag/SignIn.tag.html | 2 +- .../src/main/web/tag/UserProfile.tag.html | 84 ++++++++++++---------- 5 files changed, 52 insertions(+), 39 deletions(-) diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java index 33ece430..04dc258e 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/AuthApi.java @@ -227,6 +227,7 @@ public class AuthApi { return getLoginResponseFromPollenUser(serviceContext, securityService, securityContext, userPollenEntityRef); } + //FIXME post ou put et pas get @Path("/logout") @DELETE public Response logout(@Context SecurityService securityService, diff --git a/pollen-ui-riot-js/src/main/web/i18n/en.json b/pollen-ui-riot-js/src/main/web/i18n/en.json index 42f8a434..57a7b7a9 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/en.json +++ b/pollen-ui-riot-js/src/main/web/i18n/en.json @@ -409,6 +409,8 @@ "userProfile_loginProviders": "External accounts", "userProfile_linkProvider": "Link an external account to connect to Pollen:", "userProfile_unlinkProviderMessage": "Unlink this external account? You will not be able to connect to your Pollen account with this external account.", + "userProfile_avatar": "Avatar", + "userProfile_avatarLoadingFailed": "If your avatar does not display, check that you did not enabled the tracking protection.", "choice_description_placeholder": "You can enter a description for this choice", "date-picker_today": "Today", "date-picker_dateplaceholder": "Date", diff --git a/pollen-ui-riot-js/src/main/web/i18n/fr.json b/pollen-ui-riot-js/src/main/web/i18n/fr.json index f114a1f3..d128dacc 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/fr.json +++ b/pollen-ui-riot-js/src/main/web/i18n/fr.json @@ -409,6 +409,8 @@ "userProfile_loginProviders": "Comptes externes", "userProfile_linkProvider": "Associez un compte externe pour vous connecter à Pollen :", "userProfile_unlinkProviderMessage": "Désassossier ce compte externe ? Vous ne pourrez plus vous connectez à votre compte Pollen avec ce compte externe.", + "userProfile_avatar": "Avatar", + "userProfile_avatarLoadingFailed": "Si votre avatar ne s'affiche pas, vérifiez que vous n'avez pas activé la protection contre le pistage.", "choice_description_placeholder": "Vous pouvez saisir une description pour ce choix", "date-picker_today": "Aujourd'hui", "date-picker_dateplaceholder": "Date", diff --git a/pollen-ui-riot-js/src/main/web/tag/SignIn.tag.html b/pollen-ui-riot-js/src/main/web/tag/SignIn.tag.html index 3d1c9140..c28927a5 100644 --- a/pollen-ui-riot-js/src/main/web/tag/SignIn.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/SignIn.tag.html @@ -160,7 +160,7 @@ require("./components/HumanInput.tag.html"); } @media (orientation: landscape) { - .body-content { + .body-container { flex-basis: 50%; } } diff --git a/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html b/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html index 57fd0a0b..42e4cd7f 100644 --- a/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html @@ -141,43 +141,49 @@ require("./components/HumanInput.tag.html"); </div> </form> - <div class="providers"> - <h3 class="c-heading"><i class="fa fa-sign-in"/> {__.loginProviders}</h3> - <div class="user-credentials"> - <div each="{credential, index in user.credentials}" class="user-credential {index % 2 == 0 ? 'even' : 'odd'}"> - <i if="{authService.providerIcons[credential.provider]}" - class="fa fa-{authService.providerIcons[credential.provider]}"></i> - <span if="{!authService.providerIcons[credential.provider]}">{credential.userName}</span> - <span class="credential-name">{credential.userName} <em if="{credential.emailAddress}">({credential.emailAddress})</em></span> - <button if="{user.withPassword && user.email || user.credentials.length > 1}" - onclick="{unlinkProvider(credential.id, index)}" class="c-button u-small c-button--error"><i class="fa fa-trash"></i></button> + <div class="providers"> + <h3 class="c-heading"><i class="fa fa-sign-in"/> {__.loginProviders}</h3> + <div class="user-credentials"> + <div each="{credential, index in user.credentials}" class="user-credential {index % 2 == 0 ? 'even' : 'odd'}"> + <i if="{authService.providerIcons[credential.provider]}" + class="fa fa-{authService.providerIcons[credential.provider]}"></i> + <span if="{!authService.providerIcons[credential.provider]}">{credential.userName}</span> + <span class="credential-name">{credential.userName} <em if="{credential.emailAddress}">({credential.emailAddress})</em></span> + <button if="{user.withPassword && user.email || user.credentials.length > 1}" + onclick="{unlinkProvider(credential.id, index)}" class="c-button u-small c-button--error"><i class="fa fa-trash"></i></button> + </div> </div> - </div> - - <div class="o-form-element align-center" if="{loginProviders.length > 0}"> - <p>{__.linkProvider}</p> - <p> - <a each="{loginProvider in loginProviders}" class="provider-link" - onclick="{linkProvider(loginProvider)}"> - <i class="fa fa-{authService.providerIcons[loginProvider]}" if="{authService.providerIcons[loginProvider]}"></i> - <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> - </a> - </p> - </div> - - <div class="o-form-element align-center" if="{loginProviders.length > 0}"> - <p>Avatar</p> - <p><img src="{user.avatar}" onerror="{test}"/></p> - <p> - <a each="{loginProvider in loginProviders}" class="provider-link" - onclick="{getProviderAvatar(loginProvider)}"> - <i class="fa fa-{authService.providerIcons[loginProvider]}" if="{authService.providerIcons[loginProvider]}"></i> - <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> - </a> - </p> - </div> - </div> + <div class="o-form-element align-center" if="{loginProviders.length > 0}"> + <p>{__.linkProvider}</p> + <p> + <a each="{loginProvider in loginProviders}" class="provider-link" + onclick="{linkProvider(loginProvider)}"> + <i class="fa fa-{authService.providerIcons[loginProvider]}" if="{authService.providerIcons[loginProvider]}"></i> + <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> + </a> + </p> + </div> + </div> + + <div class="avatar"> + <h3 class="c-heading"><i class="fa fa-sign-in"/> {__.avatar}</h3> + <div class="o-form-element align-center" if="{loginProviders.length > 0}"> + <p> + <img src="{user.avatar}" onerror="{avatarLoadingFailed}"/> + <i class="fa fa-question-circle cursor-help error" if="{avatarLoadingError}" title="{__.avatarLoadingFailed}"></i> + {} + </p> + <p> + <a each="{loginProvider in loginProviders}" class="provider-link" + onclick="{getProviderAvatar(loginProvider)}"> + <i class="fa fa-{authService.providerIcons[loginProvider]}" + if="{authService.providerIcons[loginProvider]}"></i> + <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> + </a> + </p> + </div> + </div> </div> </div> @@ -197,14 +203,16 @@ require("./components/HumanInput.tag.html"); this.update(); }); + this.avatarLoadingError = false; + this.onUserChange = (user) => { this.user = user || {}; this.update(); }; -this.test = (e) => { -console.log(e) -} + this.avatarLoadingFailed = (e) => { + this.avatarLoadingError = true; + } this.resendValidation = () => { this.authService.resendValidation(this.user.email); -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/28_avatars in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 8c8503c4e5c11165e7efbddf4a9991f12d788d39 Author: Kevin Morin <morin@codelutin.com> Date: Fri Sep 22 17:42:51 2017 +0200 refs #28 finalement on stocke l'avatar dans une resource en base meme quand ça vient d'un tiers --- .../persistence/entity/PollenResourceTopiaDao.java | 12 + .../db/migration/h2/V3_0_0_11__add_avatar.sql | 2 - .../db/migration/h2/V3_0_1_2__add_avatar.sql | 3 + .../migration/postgresql/V3_0_0_11__add_avatar.sql | 2 - .../migration/postgresql/V3_0_1_2__add_avatar.sql | 3 + pollen-persistence/src/main/xmi/pollen.properties | 2 +- pollen-persistence/src/main/xmi/pollen.zargo | Bin 28419 -> 28921 bytes .../org/chorem/pollen/rest/api/v1/ApiUtils.java | 2 +- .../chorem/pollen/rest/api/v1/FavoriteListApi.java | 2 +- .../java/org/chorem/pollen/rest/api/v1/GtuApi.java | 3 + .../pollen/rest/api/v1/PollenResourceApi.java | 15 +- .../chorem/pollen/rest/api/v1/PollenUserApi.java | 4 +- .../pollen/services/bean/PollenUserBean.java | 5 +- .../AbstractResourceBean.java} | 49 +--- .../services/bean/{ => resource}/GtuMetaBean.java | 2 +- .../bean/{ => resource}/ResourceFileBean.java | 60 +--- .../ResourceMetaBean.java} | 36 ++- .../bean/{ => resource}/ResourceStreamBean.java | 50 +--- .../chorem/pollen/services/service/GtuService.java | 4 +- .../services/service/PollenResourceService.java | 25 +- .../pollen/services/service/SocialAuthService.java | 30 +- .../src/main/web/tag/UserProfile.tag.html | 312 +++++++++++---------- 22 files changed, 291 insertions(+), 332 deletions(-) diff --git a/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollenResourceTopiaDao.java b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollenResourceTopiaDao.java index 5410999c..ba1ac143 100644 --- a/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollenResourceTopiaDao.java +++ b/pollen-persistence/src/main/java/org/chorem/pollen/persistence/entity/PollenResourceTopiaDao.java @@ -21,6 +21,9 @@ package org.chorem.pollen.persistence.entity; * #L% */ +import java.util.HashMap; +import java.util.Map; + /** * Created on 24/07/14. * @@ -59,4 +62,13 @@ public class PollenResourceTopiaDao extends AbstractPollenResourceTopiaDao<Polle } } + + public PollenResource findAvatarForUser(String userId) { + String hql = "SELECT " + PollenUser.PROPERTY_AVATAR + + " FROM " + PollenUser.class.getName() + " user " + + " WHERE user." + PollenUser.PROPERTY_TOPIA_ID + " = :userId"; + Map<String, Object> params = new HashMap<>(); + params.put("userId", userId); + return findUniqueOrNull(hql, params); + } } diff --git a/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_11__add_avatar.sql b/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_11__add_avatar.sql deleted file mode 100644 index 197b01b4..00000000 --- a/pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_11__add_avatar.sql +++ /dev/null @@ -1,2 +0,0 @@ --- add user's avatar -alter table pollenUser add avatar VARCHAR(255); diff --git a/pollen-persistence/src/main/resources/db/migration/h2/V3_0_1_2__add_avatar.sql b/pollen-persistence/src/main/resources/db/migration/h2/V3_0_1_2__add_avatar.sql new file mode 100644 index 00000000..0bf88e60 --- /dev/null +++ b/pollen-persistence/src/main/resources/db/migration/h2/V3_0_1_2__add_avatar.sql @@ -0,0 +1,3 @@ +-- add user's avatar +alter table pollenUser add avatar VARCHAR(255); +alter table pollenUser ADD FOREIGN KEY (avatar) REFERENCES PollenResource(topiaId); diff --git a/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_11__add_avatar.sql b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_11__add_avatar.sql deleted file mode 100644 index 197b01b4..00000000 --- a/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_11__add_avatar.sql +++ /dev/null @@ -1,2 +0,0 @@ --- add user's avatar -alter table pollenUser add avatar VARCHAR(255); diff --git a/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_1_2__add_avatar.sql b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_1_2__add_avatar.sql new file mode 100644 index 00000000..0bf88e60 --- /dev/null +++ b/pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_1_2__add_avatar.sql @@ -0,0 +1,3 @@ +-- add user's avatar +alter table pollenUser add avatar VARCHAR(255); +alter table pollenUser ADD FOREIGN KEY (avatar) REFERENCES PollenResource(topiaId); diff --git a/pollen-persistence/src/main/xmi/pollen.properties b/pollen-persistence/src/main/xmi/pollen.properties index 19fe27c2..fb44dc92 100644 --- a/pollen-persistence/src/main/xmi/pollen.properties +++ b/pollen-persistence/src/main/xmi/pollen.properties @@ -18,7 +18,7 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # #L% ###m -model.tagvalue.version=3.0.0.11 +model.tagvalue.version=3.0.1.2 #model.tagValue.notGenerateToString=true #model.tagValue.constantPrefix=PROPERTY_ #model.tagValue.useEnumerationName=true diff --git a/pollen-persistence/src/main/xmi/pollen.zargo b/pollen-persistence/src/main/xmi/pollen.zargo index 1642eec1..9df3975b 100644 Binary files a/pollen-persistence/src/main/xmi/pollen.zargo and b/pollen-persistence/src/main/xmi/pollen.zargo differ diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ApiUtils.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ApiUtils.java index 98b7ce7c..5834b267 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ApiUtils.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/ApiUtils.java @@ -27,7 +27,7 @@ import org.apache.commons.io.IOUtils; import org.chorem.pollen.persistence.entity.ResourceType; import org.chorem.pollen.rest.api.beans.Resource64Bean; import org.chorem.pollen.services.PollenTechnicalException; -import org.chorem.pollen.services.bean.ResourceFileBean; +import org.chorem.pollen.services.bean.resource.ResourceFileBean; import org.chorem.pollen.services.bean.export.ExportBean; import org.jboss.resteasy.plugins.providers.multipart.InputPart; import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput; diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/FavoriteListApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/FavoriteListApi.java index b0f92f74..5a6fe2b6 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/FavoriteListApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/FavoriteListApi.java @@ -33,7 +33,7 @@ import org.chorem.pollen.services.bean.PaginationResultBean; import org.chorem.pollen.services.bean.PollenBean; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; -import org.chorem.pollen.services.bean.ResourceFileBean; +import org.chorem.pollen.services.bean.resource.ResourceFileBean; import org.chorem.pollen.services.bean.export.ExportBean; import org.chorem.pollen.services.service.FavoriteListImportException; import org.chorem.pollen.services.service.FavoriteListService; diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/GtuApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/GtuApi.java index 91f23de1..b28619fb 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/GtuApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/GtuApi.java @@ -1,5 +1,6 @@ package org.chorem.pollen.rest.api.v1; +<<<<<<< HEAD /*- * #%L * Pollen :: Rest Api @@ -23,6 +24,8 @@ package org.chorem.pollen.rest.api.v1; import org.chorem.pollen.services.bean.GtuMetaBean; import org.chorem.pollen.services.bean.ResourceStreamBean; +import org.chorem.pollen.services.bean.resource.GtuMetaBean; +import org.chorem.pollen.services.bean.resource.ResourceStreamBean; import org.chorem.pollen.services.service.GtuService; import javax.ws.rs.Consumes; diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java index 5a1d251f..3cb4f974 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java @@ -22,12 +22,13 @@ package org.chorem.pollen.rest.api.v1; */ import org.chorem.pollen.persistence.entity.PollenResource; +import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.rest.api.beans.Resource64Bean; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; -import org.chorem.pollen.services.bean.ResourceFileBean; -import org.chorem.pollen.services.bean.ResourceMetaBean; -import org.chorem.pollen.services.bean.ResourceStreamBean; +import org.chorem.pollen.services.bean.resource.ResourceFileBean; +import org.chorem.pollen.services.bean.resource.ResourceMetaBean; +import org.chorem.pollen.services.bean.resource.ResourceStreamBean; import org.chorem.pollen.services.service.InvalidFormException; import org.chorem.pollen.services.service.PollenResourceService; import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput; @@ -129,4 +130,12 @@ public class PollenResourceApi { pollenResourceService.deleteResource(resourceId.getEntityId()); } + + @Path("/avatar/{userId}") + @GET + public Response getUserAvatar(@Context PollenResourceService pollenResourceService, + @PathParam("userId") PollenEntityId<PollenUser> userId) { + ResourceStreamBean resource = pollenResourceService.getAvatar(userId.getEntityId()); + return Response.ok(resource.getResourceContent(), resource.getContentType()).build(); + } } diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java index 0968efa3..4e6662d8 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java @@ -158,7 +158,7 @@ public class PollenUserApi { @Path("/users/{userId}/avatar/{provider}") @POST - public String setAvatar(@Context SocialAuthService socialAuthService, + public void setAvatar(@Context SocialAuthService socialAuthService, @Context HttpServletRequest request, @PathParam("userId") PollenEntityId<PollenUser> userId, @PathParam("provider") String provider, @@ -170,6 +170,6 @@ public class PollenUserApi { request.getSession().removeAttribute(ApiUtils.SOCIAL_AUTH_MANAGER_SESSION_KEY); Gson gson = new Gson(); Map<String, String> paramsMap = gson.fromJson(providerReturn, Map.class); - return socialAuthService.setAvatarToUser(userId, socialAuthManager, paramsMap); + socialAuthService.setAvatarToUser(userId, socialAuthManager, paramsMap); } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenUserBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenUserBean.java index aea1b1d0..7af63ad3 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenUserBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollenUserBean.java @@ -84,7 +84,9 @@ public class PollenUserBean extends PollenBean<PollenUser> { }) .collect(Collectors.toList())); } - setAvatar(entity.getAvatar()); + if (entity.getAvatar() != null) { + setAvatar(entity.getAvatar().getTopiaId()); + } } @Override @@ -98,7 +100,6 @@ public class PollenUserBean extends PollenBean<PollenUser> { entity.setLanguage(getLanguage()); entity.setEmail(getEmail()); entity.setPassword(getPassword()); - entity.setAvatar(getAvatar()); return entity; diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceMetaBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/AbstractResourceBean.java similarity index 55% rename from pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceMetaBean.java rename to pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/AbstractResourceBean.java index eea72c85..685e6570 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceMetaBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/AbstractResourceBean.java @@ -1,38 +1,14 @@ -package org.chorem.pollen.services.bean; - -/* - * #%L - * Pollen :: Service - * %% - * Copyright (C) 2009 - 2017 Code Lutin, Tony Chemit - * %% - * This program is free software: you can redistribute it and/or modify - * it under the terms of the GNU Affero General Public License as published by - * the Free Software Foundation, either version 3 of the License, or - * (at your option) any later version. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU Affero General Public License - * along with this program. If not, see <http://www.gnu.org/licenses/>. - * #L% - */ +package org.chorem.pollen.services.bean.resource; import org.chorem.pollen.persistence.entity.PollenResource; import org.chorem.pollen.persistence.entity.PollenResourceImpl; import org.chorem.pollen.persistence.entity.ResourceType; - -import java.util.Date; +import org.chorem.pollen.services.bean.PollenBean; /** - * Created on 11/07/14. - * - * @author dralagen + * @author Kevin Morin (Code Lutin) */ -public class ResourceMetaBean extends PollenBean<PollenResource> { +public abstract class AbstractResourceBean extends PollenBean<PollenResource> { protected String name; @@ -42,21 +18,17 @@ public class ResourceMetaBean extends PollenBean<PollenResource> { protected ResourceType resourceType; - protected Date uploadDate; - - protected ResourceMetaBean() { - super(PollenResource.class); + protected AbstractResourceBean(Class<PollenResource> entityType) { + super(entityType); } @Override public void fromEntity(PollenResource entity) { setEntityId(entity.getTopiaId()); - setName(entity.getName()); setSize(entity.getSize()); setContentType(entity.getContentType()); setResourceType(entity.getResourceType()); - setUploadDate(entity.getTopiaCreateDate()); } @Override @@ -64,7 +36,6 @@ public class ResourceMetaBean extends PollenBean<PollenResource> { PollenResource entity = new PollenResourceImpl(); entity.setTopiaId(getEntityId()); - entity.setName(getName()); entity.setSize(getSize()); entity.setContentType(getContentType()); @@ -104,12 +75,4 @@ public class ResourceMetaBean extends PollenBean<PollenResource> { public void setResourceType(ResourceType resourceType) { this.resourceType = resourceType; } - - public Date getUploadDate() { - return uploadDate; - } - - public void setUploadDate(Date uploadDate) { - this.uploadDate = uploadDate; - } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/GtuMetaBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/GtuMetaBean.java similarity index 95% copy from pollen-services/src/main/java/org/chorem/pollen/services/bean/GtuMetaBean.java copy to pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/GtuMetaBean.java index 254ed493..d71c06c8 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/GtuMetaBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/GtuMetaBean.java @@ -1,4 +1,4 @@ -package org.chorem.pollen.services.bean; +package org.chorem.pollen.services.bean.resource; /*- * #%L diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceFileBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceFileBean.java similarity index 60% rename from pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceFileBean.java rename to pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceFileBean.java index 526d9fa2..a6326526 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceFileBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceFileBean.java @@ -1,4 +1,4 @@ -package org.chorem.pollen.services.bean; +package org.chorem.pollen.services.bean.resource; /* * #%L @@ -23,8 +23,6 @@ package org.chorem.pollen.services.bean; import org.apache.commons.io.IOUtils; import org.chorem.pollen.persistence.entity.PollenResource; -import org.chorem.pollen.persistence.entity.PollenResourceImpl; -import org.chorem.pollen.persistence.entity.ResourceType; import javax.sql.rowset.serial.SerialBlob; import java.io.File; @@ -41,37 +39,23 @@ import java.util.zip.ZipException; * * @author dralagen */ -public class ResourceFileBean extends PollenBean<PollenResource> { +public class ResourceFileBean extends AbstractResourceBean { protected File file; - protected String name; - - protected long size; - - protected String contentType; - - protected ResourceType resourceType; - public ResourceFileBean() { super(PollenResource.class); } @Override public void fromEntity(PollenResource entity) { - setEntityId(entity.getTopiaId()); - - setName(entity.getName()); - setSize(entity.getSize()); - setContentType(entity.getContentType()); + super.fromEntity(entity); setResourceType(entity.getResourceType()); } @Override public PollenResource toEntity() { - PollenResource entity = new PollenResourceImpl(); - - entity.setTopiaId(getEntityId()); + PollenResource entity = super.toEntity(); try { entity.setResourceContent(getResourceBlob()); @@ -79,11 +63,6 @@ public class ResourceFileBean extends PollenBean<PollenResource> { e.printStackTrace(); } - entity.setName(getName()); - entity.setSize(getSize()); - entity.setContentType(getContentType()); - entity.setResourceType(getResourceType()); - return entity; } @@ -95,30 +74,6 @@ public class ResourceFileBean extends PollenBean<PollenResource> { this.file = file; } - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public long getSize() { - return size; - } - - public void setSize(long size) { - this.size = size; - } - - public String getContentType() { - return contentType; - } - - public void setContentType(String contentType) { - this.contentType = contentType; - } - public Blob getResourceBlob() throws IOException, SQLException { InputStream stream; @@ -131,11 +86,4 @@ public class ResourceFileBean extends PollenBean<PollenResource> { return new SerialBlob(IOUtils.toByteArray(stream)); } - public ResourceType getResourceType() { - return resourceType; - } - - public void setResourceType(ResourceType resourceType) { - this.resourceType = resourceType; - } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/GtuMetaBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java similarity index 50% rename from pollen-services/src/main/java/org/chorem/pollen/services/bean/GtuMetaBean.java rename to pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java index 254ed493..315f854e 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/GtuMetaBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java @@ -1,10 +1,10 @@ -package org.chorem.pollen.services.bean; +package org.chorem.pollen.services.bean.resource; -/*- +/* * #%L * Pollen :: Service * %% - * Copyright (C) 2009 - 2017 CodeLutin + * Copyright (C) 2009 - 2017 Code Lutin, Tony Chemit * %% * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Affero General Public License as published by @@ -21,18 +21,34 @@ package org.chorem.pollen.services.bean; * #L% */ +import org.chorem.pollen.persistence.entity.PollenResource; + +import java.util.Date; + /** - * @author Sylvain Bavencoff - bavencoff@codelutin.com + * Created on 11/07/14. + * + * @author dralagen */ -public class GtuMetaBean extends ResourceMetaBean { +public class ResourceMetaBean extends AbstractResourceBean { + + protected Date uploadDate; - protected boolean current; + protected ResourceMetaBean() { + super(PollenResource.class); + } + + @Override + public void fromEntity(PollenResource entity) { + super.fromEntity(entity); + setUploadDate(entity.getTopiaCreateDate()); + } - public boolean isCurrent() { - return current; + public Date getUploadDate() { + return uploadDate; } - public void setCurrent(boolean current) { - this.current = current; + public void setUploadDate(Date uploadDate) { + this.uploadDate = uploadDate; } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceStreamBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceStreamBean.java similarity index 65% rename from pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceStreamBean.java rename to pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceStreamBean.java index 75cd147c..800f4520 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/ResourceStreamBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceStreamBean.java @@ -1,4 +1,4 @@ -package org.chorem.pollen.services.bean; +package org.chorem.pollen.services.bean.resource; /* * #%L @@ -23,7 +23,6 @@ package org.chorem.pollen.services.bean; import org.apache.commons.io.IOUtils; import org.chorem.pollen.persistence.entity.PollenResource; -import org.chorem.pollen.persistence.entity.PollenResourceImpl; import javax.sql.rowset.serial.SerialBlob; import java.io.IOException; @@ -36,40 +35,28 @@ import java.sql.SQLException; * * @author dralagen */ -public class ResourceStreamBean extends PollenBean<PollenResource> { +public class ResourceStreamBean extends AbstractResourceBean { protected InputStream resourceContent; - protected String name; - - protected long size; - - protected String contentType; - public ResourceStreamBean() { super(PollenResource.class); } @Override public void fromEntity(PollenResource entity) { - setEntityId(entity.getTopiaId()); + super.fromEntity(entity); try { setResourceContent(entity.getResourceContent().getBinaryStream()); } catch (SQLException e) { e.printStackTrace(); } - - setName(entity.getName()); - setSize(entity.getSize()); - setContentType(entity.getContentType()); } @Override public PollenResource toEntity() { - PollenResource entity = new PollenResourceImpl(); - - entity.setTopiaId(getEntityId()); + PollenResource entity = super.toEntity(); try { entity.setResourceContent(getResourceBlob()); @@ -77,11 +64,6 @@ public class ResourceStreamBean extends PollenBean<PollenResource> { e.printStackTrace(); } - entity.setName(getName()); - entity.setSize(getSize()); - entity.setContentType(getContentType()); - - return entity; } @@ -93,30 +75,6 @@ public class ResourceStreamBean extends PollenBean<PollenResource> { this.resourceContent = resourceContent; } - public String getName() { - return name; - } - - public void setName(String name) { - this.name = name; - } - - public long getSize() { - return size; - } - - public void setSize(long size) { - this.size = size; - } - - public String getContentType() { - return contentType; - } - - public void setContentType(String contentType) { - this.contentType = contentType; - } - public Blob getResourceBlob() throws IOException, SQLException { return new SerialBlob(IOUtils.toByteArray(getResourceContent())); } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/GtuService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/GtuService.java index d129a0bf..5e6c5e28 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/GtuService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/GtuService.java @@ -27,8 +27,8 @@ import org.chorem.pollen.persistence.entity.Poll; import org.chorem.pollen.persistence.entity.PollenResource; import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.persistence.entity.ResourceType; -import org.chorem.pollen.services.bean.GtuMetaBean; -import org.chorem.pollen.services.bean.ResourceStreamBean; +import org.chorem.pollen.services.bean.resource.GtuMetaBean; +import org.chorem.pollen.services.bean.resource.ResourceStreamBean; import org.nuiton.util.pagination.PaginationOrder; import java.util.Collections; diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenResourceService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenResourceService.java index 158b22e9..0dc1d469 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenResourceService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenResourceService.java @@ -28,9 +28,10 @@ import org.chorem.pollen.services.PollenTechnicalException; import org.chorem.pollen.services.UnitHuman; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; -import org.chorem.pollen.services.bean.ResourceFileBean; -import org.chorem.pollen.services.bean.ResourceMetaBean; -import org.chorem.pollen.services.bean.ResourceStreamBean; +import org.chorem.pollen.services.bean.resource.AbstractResourceBean; +import org.chorem.pollen.services.bean.resource.ResourceFileBean; +import org.chorem.pollen.services.bean.resource.ResourceMetaBean; +import org.chorem.pollen.services.bean.resource.ResourceStreamBean; import org.nuiton.topia.persistence.TopiaIdFactory; import javax.imageio.ImageIO; @@ -131,6 +132,17 @@ public class PollenResourceService extends PollenServiceSupport implements Polle return PollenEntityRef.of(savedResource); } + public PollenResource createAvatarResource(ResourceStreamBean resource) throws InvalidFormException { + checkNotNull(resource); + checkIsNotPersisted(resource); + + ErrorMap errorMap = checkRessource(resource); + errorMap.failIfNotEmpty(); + + // commit done by the caller + return getPollenResourceDao().create(resource.toEntity()); + } + public void deleteResource(String resourceId) { checkNotNull(resourceId); checkIsAdmin(); @@ -146,6 +158,11 @@ public class PollenResourceService extends PollenServiceSupport implements Polle commit(); } + public ResourceStreamBean getAvatar(String userId) { + PollenResource resource = getPollenResourceDao().findAvatarForUser(userId); + return toBean(ResourceStreamBean.class, resource); + } + protected PollenResource getResource0(String resourceId) { return getPollenResourceDao().forTopiaIdEquals(resourceId).findUnique(); @@ -198,7 +215,7 @@ public class PollenResourceService extends PollenServiceSupport implements Polle return resourceId.getReducedId(); } - protected ErrorMap checkRessource(ResourceFileBean resource) { + protected ErrorMap checkRessource(AbstractResourceBean resource) { ErrorMap errorMap = new ErrorMap(); if (resource.getSize() > getPollenServiceConfig().getResourceMaxSize()) { diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java index 4557276a..d47dcd63 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java @@ -32,16 +32,21 @@ import org.brickred.socialauth.util.Constants; import org.brickred.socialauth.util.OAuthConfig; import org.chorem.pollen.persistence.entity.LoginProvider; import org.chorem.pollen.persistence.entity.LoginProviderTopiaDao; +import org.chorem.pollen.persistence.entity.PollenResource; import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.persistence.entity.PollenUserImpl; import org.chorem.pollen.persistence.entity.PollenUserTopiaDao; +import org.chorem.pollen.persistence.entity.ResourceType; import org.chorem.pollen.persistence.entity.UserCredential; import org.chorem.pollen.persistence.entity.UserCredentialImpl; import org.chorem.pollen.services.bean.LoginProviderBean; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; +import org.chorem.pollen.services.bean.resource.ResourceStreamBean; import org.chorem.pollen.services.service.security.PollenEmailOrProviderAccountAlreadyUsedException; +import java.net.URL; +import java.net.URLConnection; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -257,21 +262,34 @@ public class SocialAuthService extends PollenServiceSupport { commit(); } - public String setAvatarToUser(PollenEntityId<PollenUser> userId, SocialAuthManager manager, Map<String, String> paramsMap) throws Exception { + public void setAvatarToUser(PollenEntityId<PollenUser> userId, SocialAuthManager manager, Map<String, String> paramsMap) throws Exception { checkIsConnected(); PollenUser connectedUser = getConnectedUser(); if (!connectedUser.getTopiaId().equals(userId.getEntityId())) { throw new PollenUnauthorizedException(userId.getReducedId()); } - AuthProvider provider = manager.connect(paramsMap); + PollenResourceService pollenResourceService = getPollenResourceService(); + + if (connectedUser.getAvatar() != null) { + pollenResourceService.deleteResource(connectedUser.getAvatar().getTopiaId()); + } // get profile + AuthProvider provider = manager.connect(paramsMap); Profile p = provider.getUserProfile(); - - connectedUser.setAvatar(p.getProfileImageURL()); + String avatarUrl = p.getProfileImageURL(); + URLConnection connection = new URL(avatarUrl).openConnection(); + String contentType = connection.getContentType(); + ResourceStreamBean resourceStreamBean = new ResourceStreamBean(); + resourceStreamBean.setResourceContent(connection.getInputStream()); + resourceStreamBean.setName(connectedUser.getTopiaId()); + resourceStreamBean.setContentType(contentType); + resourceStreamBean.setSize(connection.getContentLength()); + resourceStreamBean.setResourceType(ResourceType.AVATAR); + PollenResource avatarResource = pollenResourceService.createAvatarResource(resourceStreamBean); +//TODO check error in avatar downloading + connectedUser.setAvatar(avatarResource); commit(); - - return connectedUser.getAvatar(); } } diff --git a/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html b/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html index 42e4cd7f..0fcacbff 100644 --- a/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html @@ -25,163 +25,166 @@ require("./components/HumanInput.tag.html"); <h1><i class="fa fa-user"/> {__.title}</h1> <div class="main-content"> - - <form ref="identity-form" class="identity-form"> - <HumanInput onsubmit={submitIdentity}/> - <h3 class="c-heading"><i class="fa fa-address-card"/> {__.identity}</h3> - <div class="o-form-element"> - <label class="c-label" for="name">{__.name}</label> - <input class="c-field {c-field--error : errors.name}" - type="text" - name="name" - ref="name" - value={user.name} - placeholder="{__.name_placeholder}" - required - maxlength="255"> - <div if="{errors.name}" - class="c-hint--static c-hint--error"> - {errors.name} + <div class="row-content"> + <form ref="identity-form" class="identity-form column-content"> + <HumanInput onsubmit={submitIdentity}/> + <h3 class="c-heading"><i class="fa fa-address-card"/> {__.identity}</h3> + <div class="o-form-element"> + <label class="c-label" for="name">{__.name}</label> + <input class="c-field {c-field--error : errors.name}" + type="text" + name="name" + ref="name" + value={user.name} + placeholder="{__.name_placeholder}" + required + maxlength="255"> + <div if="{errors.name}" + class="c-hint--static c-hint--error"> + {errors.name} + </div> </div> - </div> - <div class="o-form-element"> - <label class="c-label" for="email">{__.email}</label> - <div class="o-field o-field--icon-right"> - <input class="c-field {c-field--error : errors.email}" - type="email" - name="email" - ref="email" - value={user.email} - placeholder="{__.email_placeholder}" - required - maxlength="255"> - <i class="fa fa-fw fa-{user.emailIsValidate ? 'check' : 'refresh'} c-icon" - title={user.emailIsValidate ? __.emailValidate : __.emailValidationWaiting}></i> - </div> - <div if="{errors.email}" - class="c-hint--static c-hint--error"> - {errors.email} + <div class="o-form-element"> + <label class="c-label" for="email">{__.email}</label> + <div class="o-field o-field--icon-right"> + <input class="c-field {c-field--error : errors.email}" + type="email" + name="email" + ref="email" + value={user.email} + placeholder="{__.email_placeholder}" + required + maxlength="255"> + <i class="fa fa-fw fa-{user.emailIsValidate ? 'check' : 'refresh'} c-icon" + title={user.emailIsValidate ? __.emailValidate : __.emailValidationWaiting}></i> + </div> + <div if="{errors.email}" + class="c-hint--static c-hint--error"> + {errors.email} + </div> </div> - </div> - <div class="actions-right"> - <button type="button" - class="c-button c-button--gost-info" - if={!user.emailIsValidate} - onclick={resendValidation}> - <i class="fa fa-paper-plane" aria-hidden="true"></i> - {__.resendValidation} - </button> - <button type="submit" - class="c-button c-button--info"> - <i class="fa fa-check" aria-hidden="true"></i> - {__.saveIdentity} - </button> - </div> - </form> - - <form ref="password-form" class="password-form"> - <HumanInput onsubmit={submitPassword}/> - <h3 class="c-heading"><i class="fa fa-key"/> {__.passwordChange}</h3> - <div class="o-form-element" if="{user.withPassword}"> - <label class="c-label" for="oldPassword">{__.oldPassword}</label> - <input class="c-field {c-field--error : errors.oldPassword}" - type="password" - name="oldPassword" - ref="oldPassword" - placeholder="{__.oldPassword_placeholder}" - required - maxlength="255"> - <div if="{errors.oldPassword}" - class="c-hint--static c-hint--error"> - {errors.oldPassword} + <div class="actions-right"> + <button type="button" + class="c-button c-button--gost-info" + if={!user.emailIsValidate} + onclick={resendValidation}> + <i class="fa fa-paper-plane" aria-hidden="true"></i> + {__.resendValidation} + </button> + <button type="submit" + class="c-button c-button--info"> + <i class="fa fa-check" aria-hidden="true"></i> + {__.saveIdentity} + </button> + </div> + </form> + + <form ref="password-form" class="password-form column-content"> + <HumanInput onsubmit={submitPassword}/> + <h3 class="c-heading"><i class="fa fa-key"/> {__.passwordChange}</h3> + <div class="o-form-element" if="{user.withPassword}"> + <label class="c-label" for="oldPassword">{__.oldPassword}</label> + <input class="c-field {c-field--error : errors.oldPassword}" + type="password" + name="oldPassword" + ref="oldPassword" + placeholder="{__.oldPassword_placeholder}" + required + maxlength="255"> + <div if="{errors.oldPassword}" + class="c-hint--static c-hint--error"> + {errors.oldPassword} + </div> </div> - </div> - <div class="o-form-element"> - <label class="c-label" for="newPassword">{__.newPassword}</label> - <input class="c-field {c-field--error : errors.newPassword}" - type="password" - name="newPassword" - ref="newPassword" - placeholder="{__.newPassword_placeholder}" - onblur="{checkNewPassword}" - required - maxlength="255"> - <div if="{errors.newPassword}" - class="c-hint--static c-hint--error"> - {errors.newPassword} + <div class="o-form-element"> + <label class="c-label" for="newPassword">{__.newPassword}</label> + <input class="c-field {c-field--error : errors.newPassword}" + type="password" + name="newPassword" + ref="newPassword" + placeholder="{__.newPassword_placeholder}" + onblur="{checkNewPassword}" + required + maxlength="255"> + <div if="{errors.newPassword}" + class="c-hint--static c-hint--error"> + {errors.newPassword} + </div> </div> - </div> - <div class="o-form-element"> - <label class="c-label" for="email">{__.repeatPassword}</label> - <input class="c-field {c-field--error : errors.repeatPassword}" - type="password" - name="repeatPassword" - ref="repeatPassword" - placeholder="{__.repeatPassword_placeholder}" - onblur="{checkPassword}" - onkeypress="{clearPasswordError}" - required - maxlength="255"> - <div if="{errors.repeatPassword}" - class="c-hint--static c-hint--error"> - {errors.repeatPassword} + <div class="o-form-element"> + <label class="c-label" for="email">{__.repeatPassword}</label> + <input class="c-field {c-field--error : errors.repeatPassword}" + type="password" + name="repeatPassword" + ref="repeatPassword" + placeholder="{__.repeatPassword_placeholder}" + onblur="{checkPassword}" + onkeypress="{clearPasswordError}" + required + maxlength="255"> + <div if="{errors.repeatPassword}" + class="c-hint--static c-hint--error"> + {errors.repeatPassword} + </div> </div> - </div> - <div class="actions-right"> - <button type="submit" - class="c-button c-button--info"> - <i class="fa fa-check" aria-hidden="true"></i> - {__.savePassword} - </button> - </div> - </form> - - <div class="providers"> - <h3 class="c-heading"><i class="fa fa-sign-in"/> {__.loginProviders}</h3> - <div class="user-credentials"> - <div each="{credential, index in user.credentials}" class="user-credential {index % 2 == 0 ? 'even' : 'odd'}"> - <i if="{authService.providerIcons[credential.provider]}" - class="fa fa-{authService.providerIcons[credential.provider]}"></i> - <span if="{!authService.providerIcons[credential.provider]}">{credential.userName}</span> - <span class="credential-name">{credential.userName} <em if="{credential.emailAddress}">({credential.emailAddress})</em></span> - <button if="{user.withPassword && user.email || user.credentials.length > 1}" - onclick="{unlinkProvider(credential.id, index)}" class="c-button u-small c-button--error"><i class="fa fa-trash"></i></button> - </div> - </div> + <div class="actions-right"> + <button type="submit" + class="c-button c-button--info"> + <i class="fa fa-check" aria-hidden="true"></i> + {__.savePassword} + </button> + </div> + </form> + </div> + <div class="row-content"> + <div class="providers column-content"> + <h3 class="c-heading"><i class="fa fa-sign-in"/> {__.loginProviders}</h3> + <div class="user-credentials"> + <div each="{credential, index in user.credentials}" class="user-credential {index % 2 == 0 ? 'even' : 'odd'}"> + <i if="{authService.providerIcons[credential.provider]}" + class="fa fa-{authService.providerIcons[credential.provider]}"></i> + <span if="{!authService.providerIcons[credential.provider]}">{credential.userName}</span> + <span class="credential-name">{credential.userName} <em if="{credential.emailAddress}">({credential.emailAddress})</em></span> + <button if="{user.withPassword && user.email || user.credentials.length > 1}" + onclick="{unlinkProvider(credential.id, index)}" class="c-button u-small c-button--error"><i class="fa fa-trash"></i></button> + </div> + </div> - <div class="o-form-element align-center" if="{loginProviders.length > 0}"> - <p>{__.linkProvider}</p> - <p> - <a each="{loginProvider in loginProviders}" class="provider-link" - onclick="{linkProvider(loginProvider)}"> - <i class="fa fa-{authService.providerIcons[loginProvider]}" if="{authService.providerIcons[loginProvider]}"></i> - <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> - </a> - </p> + <div class="o-form-element align-center" if="{loginProviders.length > 0}"> + <p>{__.linkProvider}</p> + <p> + <a each="{loginProvider in loginProviders}" class="provider-link" + onclick="{linkProvider(loginProvider)}"> + <i class="fa fa-{authService.providerIcons[loginProvider]}" if="{authService.providerIcons[loginProvider]}"></i> + <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> + </a> + </p> + </div> </div> - </div> - <div class="avatar"> - <h3 class="c-heading"><i class="fa fa-sign-in"/> {__.avatar}</h3> - <div class="o-form-element align-center" if="{loginProviders.length > 0}"> - <p> - <img src="{user.avatar}" onerror="{avatarLoadingFailed}"/> - <i class="fa fa-question-circle cursor-help error" if="{avatarLoadingError}" title="{__.avatarLoadingFailed}"></i> - {} - </p> - <p> - <a each="{loginProvider in loginProviders}" class="provider-link" - onclick="{getProviderAvatar(loginProvider)}"> - <i class="fa fa-{authService.providerIcons[loginProvider]}" - if="{authService.providerIcons[loginProvider]}"></i> - <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> - </a> - </p> + <div class="avatar column-content"> + <h3 class="c-heading"><i class="fa fa-sign-in"/> {__.avatar}</h3> + <div class="o-form-element align-center" if="{loginProviders.length > 0}"> + <p> + <!--FIXME get url from service--> + <img src="{session.configuration.endPoint}/v1/avatar/{user.id}" onerror="{avatarLoadingFailed}"/> + <i class="fa fa-question-circle cursor-help error" if="{avatarLoadingError}" title="{__.avatarLoadingFailed}"></i> + {} + </p> + <p> + <a each="{loginProvider in loginProviders}" class="provider-link" + onclick="{getProviderAvatar(loginProvider)}"> + <i class="fa fa-{authService.providerIcons[loginProvider]}" + if="{authService.providerIcons[loginProvider]}"></i> + <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> + </a> + </p> + </div> </div> </div> </div> @@ -189,10 +192,10 @@ require("./components/HumanInput.tag.html"); <script type="es6"> this.loaded = false; - let session = require("../js/Session"); - this.installBundle(session, "userProfile"); + this.session = require("../js/Session"); + this.installBundle(this.session, "userProfile"); this.errors = {}; - this.user = session.getUser() || {}; + this.user = this.session.getUser() || {}; let userService = require("../js/UserService"); this.authService = require("../js/AuthService"); let Message = require("../js/Message"); @@ -224,7 +227,7 @@ require("./components/HumanInput.tag.html"); this.user.name = this.refs.name.value; this.user.email = this.refs.email.value; userService.saveUser(this.user).then(() => { - session.updateUser(); + this.session.updateUser(); this.bus.trigger("message", new Message(this._l("updatedIdentity"), "success")); }); }; @@ -257,7 +260,7 @@ require("./components/HumanInput.tag.html"); this.refs.newPassword.value = ""; this.refs.repeatPassword.value = ""; this.update(); - session.updateUser(); + this.session.updateUser(); this.bus.trigger("message", new Message(this._l("updatedPassword"), "success")); }) .catch((errors) => { @@ -304,10 +307,19 @@ require("./components/HumanInput.tag.html"); .main-content { display: flex; flex-wrap: wrap; + flex-direction: column; + max-width: 1200px; + margin: auto; + } + + .main-content .row-content { + display: flex; + flex-wrap: wrap; + flex-direction: row; justify-content: space-around; } - .main-content > form { + .main-content .column-content { flex-grow: 1; max-width: 500px; padding: 0 5px; -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/28_avatars in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit c0153a8599aeab4c0b35f79cc3f449fdc978a26e Author: Kevin Morin <morin@codelutin.com> Date: Tue Sep 26 10:55:28 2017 +0200 refs #28 forumlaire d'upload de l'avatar --- .../pollen/rest/api/v1/PollenResourceApi.java | 8 -- .../chorem/pollen/rest/api/v1/PollenUserApi.java | 35 +++++++- .../services/service/PollenResourceService.java | 2 +- .../services/service/PollenServiceSupport.java | 4 + .../pollen/services/service/PollenUserService.java | 26 +++++- .../pollen/services/service/SocialAuthService.java | 7 +- .../services/service/security/SecurityService.java | 10 +++ pollen-ui-riot-js/src/main/web/i18n/en.json | 2 +- pollen-ui-riot-js/src/main/web/i18n/fr.json | 4 +- pollen-ui-riot-js/src/main/web/js/FetchService.js | 1 - pollen-ui-riot-js/src/main/web/js/UserService.js | 17 +++- pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html | 2 +- .../src/main/web/tag/PollenHeader.tag.html | 3 +- .../src/main/web/tag/UserProfile.tag.html | 95 ++++++++++++++++------ 14 files changed, 164 insertions(+), 52 deletions(-) diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java index 3cb4f974..7decb52b 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenResourceApi.java @@ -22,7 +22,6 @@ package org.chorem.pollen.rest.api.v1; */ import org.chorem.pollen.persistence.entity.PollenResource; -import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.rest.api.beans.Resource64Bean; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; @@ -131,11 +130,4 @@ public class PollenResourceApi { pollenResourceService.deleteResource(resourceId.getEntityId()); } - @Path("/avatar/{userId}") - @GET - public Response getUserAvatar(@Context PollenResourceService pollenResourceService, - @PathParam("userId") PollenEntityId<PollenUser> userId) { - ResourceStreamBean resource = pollenResourceService.getAvatar(userId.getEntityId()); - return Response.ok(resource.getResourceContent(), resource.getContentType()).build(); - } } diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java index 4e6662d8..d3740082 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/PollenUserApi.java @@ -23,6 +23,7 @@ package org.chorem.pollen.rest.api.v1; import com.google.gson.Gson; import org.brickred.socialauth.SocialAuthManager; +import org.chorem.pollen.persistence.entity.PollenResource; import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.persistence.entity.UserCredential; import org.chorem.pollen.rest.api.beans.ChangePasswordBean; @@ -31,11 +32,15 @@ import org.chorem.pollen.services.bean.PaginationResultBean; import org.chorem.pollen.services.bean.PollenEntityId; import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.bean.PollenUserBean; +import org.chorem.pollen.services.bean.resource.ResourceFileBean; +import org.chorem.pollen.services.bean.resource.ResourceStreamBean; import org.chorem.pollen.services.service.InvalidFormException; +import org.chorem.pollen.services.service.PollenResourceService; import org.chorem.pollen.services.service.PollenUserService; import org.chorem.pollen.services.service.SocialAuthService; import org.chorem.pollen.services.service.security.PollenInvalidEmailActivationTokenException; import org.chorem.pollen.services.service.security.PollenSecurityContext; +import org.jboss.resteasy.plugins.providers.multipart.MultipartFormDataInput; import javax.servlet.http.HttpServletRequest; import javax.ws.rs.BeanParam; @@ -50,6 +55,7 @@ import javax.ws.rs.Produces; import javax.ws.rs.QueryParam; import javax.ws.rs.core.Context; import javax.ws.rs.core.MediaType; +import javax.ws.rs.core.Response; import java.util.Map; import java.util.Objects; @@ -156,11 +162,10 @@ public class PollenUserApi { socialAuthService.deleteUserCredential(credentialId); } - @Path("/users/{userId}/avatar/{provider}") + @Path("/user/avatar/{provider}") @POST public void setAvatar(@Context SocialAuthService socialAuthService, @Context HttpServletRequest request, - @PathParam("userId") PollenEntityId<PollenUser> userId, @PathParam("provider") String provider, String providerReturn) throws Exception { @@ -170,6 +175,30 @@ public class PollenUserApi { request.getSession().removeAttribute(ApiUtils.SOCIAL_AUTH_MANAGER_SESSION_KEY); Gson gson = new Gson(); Map<String, String> paramsMap = gson.fromJson(providerReturn, Map.class); - socialAuthService.setAvatarToUser(userId, socialAuthManager, paramsMap); + socialAuthService.setAvatarToUser(socialAuthManager, paramsMap); + } + + @Path("/users/{userId}/avatar") + @GET + public Response getUserAvatar(@Context PollenResourceService pollenResourceService, + @PathParam("userId") PollenEntityId<PollenUser> userId) { + ResourceStreamBean resource = pollenResourceService.getAvatar(userId.getEntityId()); + return Response.ok(resource.getResourceContent(), resource.getContentType()).build(); + } + + @Path("/user/avatar") + @POST + @Consumes(MediaType.MULTIPART_FORM_DATA) + @Produces(MediaType.APPLICATION_JSON) + public PollenEntityRef<PollenResource> createResource(@Context PollenUserService pollenUserService, + MultipartFormDataInput input) throws InvalidFormException { + ResourceFileBean resourceBean = ApiUtils.multipartToResourceBean(input, "avatar"); + return pollenUserService.setAvatar(resourceBean); + } + + @Path("/user/avatar") + @DELETE + public void deleteUserAvatar(@Context PollenUserService pollenUserService) { + pollenUserService.deleteAvatar(); } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenResourceService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenResourceService.java index 0dc1d469..288a7992 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenResourceService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenResourceService.java @@ -132,7 +132,7 @@ public class PollenResourceService extends PollenServiceSupport implements Polle return PollenEntityRef.of(savedResource); } - public PollenResource createAvatarResource(ResourceStreamBean resource) throws InvalidFormException { + public PollenResource createAvatarResource(AbstractResourceBean resource) throws InvalidFormException { checkNotNull(resource); checkIsNotPersisted(resource); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java index 586a2947..a93516af 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenServiceSupport.java @@ -265,6 +265,10 @@ public abstract class PollenServiceSupport implements PollenService { getSecurityService().checkIsConnected(); } + public void checkIsConnected(String userId) { + getSecurityService().checkIsConnected(userId); + } + public void checkIsAdmin() { getSecurityService().checkIsAdmin(); } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUserService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUserService.java index f911963a..63e9c366 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUserService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUserService.java @@ -26,15 +26,18 @@ import org.apache.commons.lang3.StringUtils; import org.apache.shiro.util.CollectionUtils; import org.chorem.pollen.persistence.entity.Comment; import org.chorem.pollen.persistence.entity.PollenPrincipal; +import org.chorem.pollen.persistence.entity.PollenResource; import org.chorem.pollen.persistence.entity.PollenToken; import org.chorem.pollen.persistence.entity.PollenUser; import org.chorem.pollen.persistence.entity.PollenUserTopiaDao; +import org.chorem.pollen.persistence.entity.ResourceType; import org.chorem.pollen.persistence.entity.Vote; import org.chorem.pollen.services.PollenService; import org.chorem.pollen.services.bean.PaginationParameterBean; import org.chorem.pollen.services.bean.PaginationResultBean; import org.chorem.pollen.services.bean.PollenEntityRef; import org.chorem.pollen.services.bean.PollenUserBean; +import org.chorem.pollen.services.bean.resource.ResourceFileBean; import org.chorem.pollen.services.service.security.PollenInvalidEmailActivationTokenException; import org.chorem.pollen.services.service.security.PollenInvalidPasswordException; import org.nuiton.util.pagination.PaginationOrder; @@ -154,7 +157,6 @@ public class PollenUserService extends PollenServiceSupport implements PollenSer PollenUser user = checkAndGetConnectedUser(); checkNotNull(newPassword); - ErrorMap errorMap = new ErrorMap(); boolean passwordNotBlank = checkNotBlank(errorMap, "newPassword", newPassword, l(getLocale(), "pollen.error.user.passwordEmpty")); @@ -262,6 +264,28 @@ public class PollenUserService extends PollenServiceSupport implements PollenSer } + public void deleteAvatar() { + checkIsConnected(); + PollenUser user = getConnectedUser(); + if (user.getAvatar() != null) { + getPollenResourceService().deleteResource(user.getAvatar().getTopiaId()); + } + commit(); + } + + public PollenEntityRef<PollenResource> setAvatar(ResourceFileBean resourceBean) throws InvalidFormException { + checkIsConnected(); + resourceBean.setResourceType(ResourceType.AVATAR); + PollenResource avatarResource = getPollenResourceService().createAvatarResource(resourceBean); + PollenUser user = getConnectedUser(); + if (user.getAvatar() != null) { + getPollenResourceService().deleteResource(user.getAvatar().getTopiaId()); + } + user.setAvatar(avatarResource); + commit(); + return PollenEntityRef.of(avatarResource); + } + protected ErrorMap checkPollenUser(PollenUserBean user) { ErrorMap errors = new ErrorMap(); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java index d47dcd63..cd31a21c 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java @@ -115,7 +115,6 @@ public class SocialAuthService extends PollenServiceSupport { Map<String, String> paramsMap) throws Exception { PollenUser connectedUser = checkAndGetConnectedUser(); - AuthProvider provider = manager.connect(paramsMap); // get profile @@ -262,13 +261,9 @@ public class SocialAuthService extends PollenServiceSupport { commit(); } - public void setAvatarToUser(PollenEntityId<PollenUser> userId, SocialAuthManager manager, Map<String, String> paramsMap) throws Exception { + public void setAvatarToUser(SocialAuthManager manager, Map<String, String> paramsMap) throws Exception { checkIsConnected(); PollenUser connectedUser = getConnectedUser(); - if (!connectedUser.getTopiaId().equals(userId.getEntityId())) { - throw new PollenUnauthorizedException(userId.getReducedId()); - } - PollenResourceService pollenResourceService = getPollenResourceService(); if (connectedUser.getAvatar() != null) { diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/SecurityService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/SecurityService.java index f351b350..6ab376a2 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/security/SecurityService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/security/SecurityService.java @@ -114,6 +114,16 @@ public class SecurityService extends PollenServiceSupport { } @Override + public void checkIsConnected(String userId) { + + PollenSecurityContext securityContext = getSecurityContext(); + if (!securityContext.isConnected() || !securityContext.getPollenUser().getTopiaId().equals(userId)) { + throw new PollenUnauthorizedException("connected"); + } + + } + + @Override public void checkIsAdmin() { PollenSecurityContext securityContext = getSecurityContext(); diff --git a/pollen-ui-riot-js/src/main/web/i18n/en.json b/pollen-ui-riot-js/src/main/web/i18n/en.json index 57a7b7a9..912c8b43 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/en.json +++ b/pollen-ui-riot-js/src/main/web/i18n/en.json @@ -410,7 +410,7 @@ "userProfile_linkProvider": "Link an external account to connect to Pollen:", "userProfile_unlinkProviderMessage": "Unlink this external account? You will not be able to connect to your Pollen account with this external account.", "userProfile_avatar": "Avatar", - "userProfile_avatarLoadingFailed": "If your avatar does not display, check that you did not enabled the tracking protection.", + "userProfile_deleteAvatarMessage": "Remove your avatar?", "choice_description_placeholder": "You can enter a description for this choice", "date-picker_today": "Today", "date-picker_dateplaceholder": "Date", diff --git a/pollen-ui-riot-js/src/main/web/i18n/fr.json b/pollen-ui-riot-js/src/main/web/i18n/fr.json index d128dacc..cc557701 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/fr.json +++ b/pollen-ui-riot-js/src/main/web/i18n/fr.json @@ -410,7 +410,9 @@ "userProfile_linkProvider": "Associez un compte externe pour vous connecter à Pollen :", "userProfile_unlinkProviderMessage": "Désassossier ce compte externe ? Vous ne pourrez plus vous connectez à votre compte Pollen avec ce compte externe.", "userProfile_avatar": "Avatar", - "userProfile_avatarLoadingFailed": "Si votre avatar ne s'affiche pas, vérifiez que vous n'avez pas activé la protection contre le pistage.", + "userProfile_deleteAvatarMessage": "Supprimer votre avatar ?", + "userProfile_uploadAvatar": "Téléverser un fichier", + "userProfile_getProviderAvatar": "ou utiliser votre avatar d'un service tiers", "choice_description_placeholder": "Vous pouvez saisir une description pour ce choix", "date-picker_today": "Aujourd'hui", "date-picker_dateplaceholder": "Date", diff --git a/pollen-ui-riot-js/src/main/web/js/FetchService.js b/pollen-ui-riot-js/src/main/web/js/FetchService.js index ae3de5a7..637f7e28 100644 --- a/pollen-ui-riot-js/src/main/web/js/FetchService.js +++ b/pollen-ui-riot-js/src/main/web/js/FetchService.js @@ -80,7 +80,6 @@ class FetchService { return this.fetch(url, "GET"); } - _addParamsToUrl(url, params) { if (params) { let query = "?"; diff --git a/pollen-ui-riot-js/src/main/web/js/UserService.js b/pollen-ui-riot-js/src/main/web/js/UserService.js index d1cceefa..b54ecc0f 100644 --- a/pollen-ui-riot-js/src/main/web/js/UserService.js +++ b/pollen-ui-riot-js/src/main/web/js/UserService.js @@ -82,11 +82,24 @@ class UserService extends FetchService { return this.post(url); } - getProviderAvatar(userId, query) { - let url = this._getUrlPrefix(userId) + "/avatar/" + query.loginProvider; + setProviderAvatar(query) { + let url = this._getUserUrlPrefix() + "/avatar/" + query.loginProvider; let body = JSON.stringify(query); return this.post(url, body); } + + getUserAvatarUrl(userId) { + return window.pollenConf.endPoint + this._getUsersUrlPrefix(userId) + "/avatar"; + } + + setUserAvatar(avatar) { + let url = this._getUserUrlPrefix() + "/avatar"; + return this.form(url, {avatar: avatar}, true); + } + + deleteAvatar() { + return this.doDelete(this._getUserUrlPrefix() + "/avatar"); + } } module.exports = singleton(UserService); diff --git a/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html b/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html index ef16fc1b..b192e896 100644 --- a/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/Pollen.tag.html @@ -308,7 +308,7 @@ require("./popup/GtuChangeModal.tag.html"); } else if (q.action === "avatar" && session.isConnected()) { let callback = (user) => { - userService.getProviderAvatar(user.id, q).then(() => { + userService.setProviderAvatar(q).then(() => { location.replace(session.pollenUIContext.uiEndPoint + "/#user/profile"); }, (e) => { e.text().then(label => { diff --git a/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html b/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html index 9712a278..e9dc0480 100644 --- a/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html @@ -22,6 +22,7 @@ */ require("./HeaderI18n.tag.html"); require("./popup/FeedbackModal.tag.html"); +require("./components/LetterAvatar.tag.html"); <PollenHeader> <a class="header-home instance-title" href="#home" target="_top"></a> @@ -46,7 +47,7 @@ require("./popup/FeedbackModal.tag.html"); <div class="dropdown" if={user}> <a class="header-link"> - <i class="fa fa-user-circle"/> + <LetterAvatar name={user && user.name} rounded="true"/> <span class="user-name action-label"> {user && user.name}</span> </a> <div class="dropdown-content right"> diff --git a/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html b/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html index 0fcacbff..5e89f949 100644 --- a/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html @@ -19,6 +19,7 @@ #L% --> require("./components/HumanInput.tag.html"); +require("./components/LetterAvatar.tag.html"); <UserProfile> <div class="container"> @@ -169,21 +170,32 @@ require("./components/HumanInput.tag.html"); <div class="avatar column-content"> <h3 class="c-heading"><i class="fa fa-sign-in"/> {__.avatar}</h3> - <div class="o-form-element align-center" if="{loginProviders.length > 0}"> - <p> - <!--FIXME get url from service--> - <img src="{session.configuration.endPoint}/v1/avatar/{user.id}" onerror="{avatarLoadingFailed}"/> - <i class="fa fa-question-circle cursor-help error" if="{avatarLoadingError}" title="{__.avatarLoadingFailed}"></i> - {} - </p> - <p> - <a each="{loginProvider in loginProviders}" class="provider-link" - onclick="{getProviderAvatar(loginProvider)}"> - <i class="fa fa-{authService.providerIcons[loginProvider]}" - if="{authService.providerIcons[loginProvider]}"></i> - <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> - </a> - </p> + <div class="avatar-container"> + <div class="avatar-column" if="{user.avatar}"> + <img src="{userService.getUserAvatarUrl(user.id)}"/> + <button onclick="{deleteAvatar}" class="c-button u-small c-button--error"><i class="fa fa-trash"></i></button> + </div> + <LetterAvatar class="avatar-column" name={user && user.name || ""} if="{!user.avatar}"/> + <div class="form-column"> + <div class="o-form-element"> + <label class="c-label" for="avatar">{__.uploadAvatar}</label> + <span class="c-input-group"> + <input type="file" class="c-field" ref="avatar" required/> + <button class="c-button" onclick="{uploadAvatar}"><i class="fa fa-upload"></i></button> + </span> + </div> + <div class="align-center" if="{loginProviders.length > 0}"> + {__.getProviderAvatar} + <div> + <a each="{loginProvider in loginProviders}" class="provider-link" + onclick="{getProviderAvatar(loginProvider)}"> + <i class="fa fa-{authService.providerIcons[loginProvider]}" + if="{authService.providerIcons[loginProvider]}"></i> + <span if="{!authService.providerIcons[loginProvider]}">{loginProvider}</span> + </a> + </div> + </div> + </div> </div> </div> </div> @@ -196,7 +208,7 @@ require("./components/HumanInput.tag.html"); this.installBundle(this.session, "userProfile"); this.errors = {}; this.user = this.session.getUser() || {}; - let userService = require("../js/UserService"); + this.userService = require("../js/UserService"); this.authService = require("../js/AuthService"); let Message = require("../js/Message"); @@ -206,17 +218,11 @@ require("./components/HumanInput.tag.html"); this.update(); }); - this.avatarLoadingError = false; - this.onUserChange = (user) => { this.user = user || {}; this.update(); }; - this.avatarLoadingFailed = (e) => { - this.avatarLoadingError = true; - } - this.resendValidation = () => { this.authService.resendValidation(this.user.email); }; @@ -226,7 +232,7 @@ require("./components/HumanInput.tag.html"); e.stopPropagation(); this.user.name = this.refs.name.value; this.user.email = this.refs.email.value; - userService.saveUser(this.user).then(() => { + this.userService.saveUser(this.user).then(() => { this.session.updateUser(); this.bus.trigger("message", new Message(this._l("updatedIdentity"), "success")); }); @@ -253,7 +259,7 @@ require("./components/HumanInput.tag.html"); if (this.errors.repeatPassword === undefined) { let oldPassword = this.user.withPassword ? this.refs.oldPassword.value : null; let newPassword = this.refs.newPassword.value; - userService.changePassword(oldPassword, newPassword).then(() => { + this.userService.changePassword(oldPassword, newPassword).then(() => { if (this.user.withPassword) { this.refs.oldPassword.value = ""; } @@ -283,14 +289,14 @@ require("./components/HumanInput.tag.html"); if (!confirm) { return Promise.reject(); } - return userService.unlinkProvider(credentialId) + return this.userService.unlinkProvider(credentialId); }).then(result => { this.user.credentials.splice(index, 1); this.update(); }); }; - getProviderAvatar= (provider) => (e) => { + this.getProviderAvatar = (provider) => (e) => { let redirection = encodeURIComponent(location.origin + location.pathname + "?loginProvider=" + provider + "&action=avatar"); this.authService.getLoginProviderUrl(provider, redirection).then(result => { @@ -298,6 +304,26 @@ require("./components/HumanInput.tag.html"); }); }; + this.deleteAvatar = e => { + this.confirm(this.__.deleteAvatarMessage).then((confirm) => { + if (!confirm) { + return Promise.reject(); + } + return this.userService.deleteAvatar(); + }).then(result => { + this.user.avatar = null; + this.update(); + }); + }; + +//TODO check size and all + this.uploadAvatar = e => { + this.userService.setUserAvatar(this.refs.avatar.files[0]).then((result) => { + this.user.avatar = result; + this.update(); + }); + } + this.listen("user", this.onUserChange); </script> @@ -331,6 +357,7 @@ require("./components/HumanInput.tag.html"); .user-credentials { width: 100%; + margin-top: 20px; } .user-credential { @@ -354,6 +381,22 @@ require("./components/HumanInput.tag.html"); font-size: 2em; } + .avatar-container { + display: flex; + flex-direction: row; + } + + .avatar-column { + display: flex; + flex-direction: column; + margin: 20px 20px 0 0; + } + + .form-column { + display: flex; + flex-direction: column; + } + </style> </UserProfile> -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/28_avatars in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit a9ba220a76c759a9daf6527930fb88fb6156245d Author: Kevin Morin <morin@codelutin.com> Date: Thu Sep 28 11:12:43 2017 +0200 refs #28 utilisation de l'avatar --- .../java/org/chorem/pollen/rest/api/v1/GtuApi.java | 3 -- .../org/chorem/pollen/services/bean/PollBean.java | 13 ++++++++ .../services/bean/resource/ResourceMetaBean.java | 2 +- .../pollen/services/service/PollService.java | 4 +++ .../pollen/services/service/PollenUserService.java | 8 +++-- .../pollen/services/service/SocialAuthService.java | 5 ++- .../src/main/web/js/ResourceService.js | 4 +++ .../src/main/web/tag/PollenHeader.tag.html | 4 +-- .../src/main/web/tag/UserProfile.tag.html | 18 ++++++----- .../src/main/web/tag/components/Avatar.tag.html | 36 ++++++++++++++++++++++ .../web/tag/favoriteList/FavoriteList.tag.html | 2 -- .../src/main/web/tag/poll/Choice.tag.html | 3 +- .../src/main/web/tag/poll/ChoiceView.tag.html | 6 ++-- .../src/main/web/tag/poll/PollCard.tag.html | 3 +- 14 files changed, 84 insertions(+), 27 deletions(-) diff --git a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/GtuApi.java b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/GtuApi.java index b28619fb..ebb04d88 100644 --- a/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/GtuApi.java +++ b/pollen-rest-api/src/main/java/org/chorem/pollen/rest/api/v1/GtuApi.java @@ -1,6 +1,5 @@ package org.chorem.pollen.rest.api.v1; -<<<<<<< HEAD /*- * #%L * Pollen :: Rest Api @@ -22,8 +21,6 @@ package org.chorem.pollen.rest.api.v1; * #L% */ -import org.chorem.pollen.services.bean.GtuMetaBean; -import org.chorem.pollen.services.bean.ResourceStreamBean; import org.chorem.pollen.services.bean.resource.GtuMetaBean; import org.chorem.pollen.services.bean.resource.ResourceStreamBean; import org.chorem.pollen.services.service.GtuService; diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java index c382bafa..7b3593f0 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/PollBean.java @@ -146,6 +146,8 @@ public class PollBean extends PollenBean<Poll> { protected boolean gtuValidated; + protected String creatorAvatar; + @Override public void fromEntity(Poll entity) { @@ -165,6 +167,9 @@ public class PollBean extends PollenBean<Poll> { setCreatorName(entity.getCreator().getName()); setCreatorEmail(entity.getCreator().getEmail()); + if (entity.getCreator().getPollenUser() != null) { + setCreatorAvatar(entity.getCreator().getPollenUser().getAvatar().getTopiaId()); + } } @@ -573,4 +578,12 @@ public class PollBean extends PollenBean<Poll> { public void setGtuValidated(boolean gtuValidated) { this.gtuValidated = gtuValidated; } + + public String getCreatorAvatar() { + return creatorAvatar; + } + + public void setCreatorAvatar(String creatorAvatar) { + this.creatorAvatar = creatorAvatar; + } } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java index 315f854e..4934c1f1 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java @@ -34,7 +34,7 @@ public class ResourceMetaBean extends AbstractResourceBean { protected Date uploadDate; - protected ResourceMetaBean() { + public ResourceMetaBean() { super(PollenResource.class); } diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java index dc7f72d2..60d488c7 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollService.java @@ -107,6 +107,10 @@ public class PollService extends PollenServiceSupport { input.setGtuValidated(getGtuService().isPollGtuValidated(input.getEntityId())); + if (input.getCreatorAvatar() != null) { + input.setCreatorAvatar(getPollenResourceService().getReduceIdByTopiaId(input.getCreatorAvatar())); + } + return input; }; diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUserService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUserService.java index 63e9c366..bd0d0677 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUserService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/PollenUserService.java @@ -62,7 +62,9 @@ public class PollenUserService extends PollenServiceSupport implements PollenSer private final Function<PollenUserBean, PollenUserBean> pollenUserFunction = input -> { input.setPassword(null); input.setGtuValidated(getGtuService().isUserGtuValidated(input.getEntityId())); - + if (input.getAvatar() != null) { + input.setAvatar(getPollenResourceService().getReduceIdByTopiaId(input.getAvatar())); + } return input; }; @@ -268,7 +270,7 @@ public class PollenUserService extends PollenServiceSupport implements PollenSer checkIsConnected(); PollenUser user = getConnectedUser(); if (user.getAvatar() != null) { - getPollenResourceService().deleteResource(user.getAvatar().getTopiaId()); + getPollenResourceDao().delete(user.getAvatar()); } commit(); } @@ -279,7 +281,7 @@ public class PollenUserService extends PollenServiceSupport implements PollenSer PollenResource avatarResource = getPollenResourceService().createAvatarResource(resourceBean); PollenUser user = getConnectedUser(); if (user.getAvatar() != null) { - getPollenResourceService().deleteResource(user.getAvatar().getTopiaId()); + getPollenResourceDao().delete(user.getAvatar()); } user.setAvatar(avatarResource); commit(); diff --git a/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java b/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java index cd31a21c..71c3a6a7 100644 --- a/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java +++ b/pollen-services/src/main/java/org/chorem/pollen/services/service/SocialAuthService.java @@ -262,12 +262,11 @@ public class SocialAuthService extends PollenServiceSupport { } public void setAvatarToUser(SocialAuthManager manager, Map<String, String> paramsMap) throws Exception { - checkIsConnected(); - PollenUser connectedUser = getConnectedUser(); + PollenUser connectedUser = checkAndGetConnectedUser(); PollenResourceService pollenResourceService = getPollenResourceService(); if (connectedUser.getAvatar() != null) { - pollenResourceService.deleteResource(connectedUser.getAvatar().getTopiaId()); + getPollenResourceDao().delete(connectedUser.getAvatar()); } // get profile diff --git a/pollen-ui-riot-js/src/main/web/js/ResourceService.js b/pollen-ui-riot-js/src/main/web/js/ResourceService.js index 9001f361..7de1ccc0 100644 --- a/pollen-ui-riot-js/src/main/web/js/ResourceService.js +++ b/pollen-ui-riot-js/src/main/web/js/ResourceService.js @@ -52,6 +52,10 @@ class ResourceService extends FetchService { return this.get(url); } + getPreviewUrl(resourceId) { + return this.endPoint + this._getUrlPrefix(resourceId) + "/preview"; + } + getMeta(resourceId) { let url = this._getUrlPrefix(resourceId) + "/meta"; return this.get(url); diff --git a/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html b/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html index e9dc0480..05a0c123 100644 --- a/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/PollenHeader.tag.html @@ -22,7 +22,7 @@ */ require("./HeaderI18n.tag.html"); require("./popup/FeedbackModal.tag.html"); -require("./components/LetterAvatar.tag.html"); +require("./components/Avatar.tag.html"); <PollenHeader> <a class="header-home instance-title" href="#home" target="_top"></a> @@ -47,7 +47,7 @@ require("./components/LetterAvatar.tag.html"); <div class="dropdown" if={user}> <a class="header-link"> - <LetterAvatar name={user && user.name} rounded="true"/> + <Avatar avatar={user.avatar} name={user.name} rounded="true"/> <span class="user-name action-label"> {user && user.name}</span> </a> <div class="dropdown-content right"> diff --git a/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html b/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html index 5e89f949..5e0cf192 100644 --- a/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/UserProfile.tag.html @@ -172,7 +172,7 @@ require("./components/LetterAvatar.tag.html"); <h3 class="c-heading"><i class="fa fa-sign-in"/> {__.avatar}</h3> <div class="avatar-container"> <div class="avatar-column" if="{user.avatar}"> - <img src="{userService.getUserAvatarUrl(user.id)}"/> + <img src="{resourceService.getPreviewUrl(user.avatar)}"/> <button onclick="{deleteAvatar}" class="c-button u-small c-button--error"><i class="fa fa-trash"></i></button> </div> <LetterAvatar class="avatar-column" name={user && user.name || ""} if="{!user.avatar}"/> @@ -208,8 +208,9 @@ require("./components/LetterAvatar.tag.html"); this.installBundle(this.session, "userProfile"); this.errors = {}; this.user = this.session.getUser() || {}; - this.userService = require("../js/UserService"); + let userService = require("../js/UserService"); this.authService = require("../js/AuthService"); + this.resourceService = require("../js/ResourceService"); let Message = require("../js/Message"); this.loginProviders = []; @@ -232,7 +233,7 @@ require("./components/LetterAvatar.tag.html"); e.stopPropagation(); this.user.name = this.refs.name.value; this.user.email = this.refs.email.value; - this.userService.saveUser(this.user).then(() => { + userService.saveUser(this.user).then(() => { this.session.updateUser(); this.bus.trigger("message", new Message(this._l("updatedIdentity"), "success")); }); @@ -259,7 +260,7 @@ require("./components/LetterAvatar.tag.html"); if (this.errors.repeatPassword === undefined) { let oldPassword = this.user.withPassword ? this.refs.oldPassword.value : null; let newPassword = this.refs.newPassword.value; - this.userService.changePassword(oldPassword, newPassword).then(() => { + userService.changePassword(oldPassword, newPassword).then(() => { if (this.user.withPassword) { this.refs.oldPassword.value = ""; } @@ -289,7 +290,7 @@ require("./components/LetterAvatar.tag.html"); if (!confirm) { return Promise.reject(); } - return this.userService.unlinkProvider(credentialId); + return userService.unlinkProvider(credentialId); }).then(result => { this.user.credentials.splice(index, 1); this.update(); @@ -309,7 +310,7 @@ require("./components/LetterAvatar.tag.html"); if (!confirm) { return Promise.reject(); } - return this.userService.deleteAvatar(); + return userService.deleteAvatar(); }).then(result => { this.user.avatar = null; this.update(); @@ -318,8 +319,9 @@ require("./components/LetterAvatar.tag.html"); //TODO check size and all this.uploadAvatar = e => { - this.userService.setUserAvatar(this.refs.avatar.files[0]).then((result) => { - this.user.avatar = result; + userService.setUserAvatar(this.refs.avatar.files[0]).then((result) => { + console.log(result); + this.user.avatar = result.id; this.update(); }); } diff --git a/pollen-ui-riot-js/src/main/web/tag/components/Avatar.tag.html b/pollen-ui-riot-js/src/main/web/tag/components/Avatar.tag.html new file mode 100644 index 00000000..b5e875da --- /dev/null +++ b/pollen-ui-riot-js/src/main/web/tag/components/Avatar.tag.html @@ -0,0 +1,36 @@ +require("./LetterAvatar.tag.html"); +<Avatar> + <LetterAvatar name={opts.name} rounded={opts.rounded} if={!opts.avatar} /> + + <div class="avatar {rounded: opts.rounded}" + style="background-image: url('{resourceService.getPreviewUrl(opts.avatar)}');" + show={opts.avatar}> + </div> + + <script> + this.session = require("../../js/Session"); + this.installBundle(this.session, "avatar"); + this.resourceService = require("../../js/ResourceService"); + this.avatarLoaded = false; + + this.onAvatarLoaded = e => { + this.avatarLoaded = true; + this.update(); + }; + </script> + + <style> + + .avatar { + width: 50px; + height:50px; + background-size: 50px 50px; + background-position: center; + background-repeat: no-repeat; + } + .avatar.rounded { + border-radius: 100%; + } + + </style> +</Avatar> \ No newline at end of file diff --git a/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteList.tag.html b/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteList.tag.html index ceac20ac..32733a09 100644 --- a/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteList.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/favoriteList/FavoriteList.tag.html @@ -164,8 +164,6 @@ require("../components/LoadingCard.tag.html"); favoriteListService.favoriteList(this.favoriteList.id).then(results => { this.favoriteList = results; this.loaded = true; - console.log("reloadFavoriteListInfos"); - console.log(results); this.update(); }); }; diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/Choice.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/Choice.tag.html index 46a9cacc..2046ce78 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/Choice.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/Choice.tag.html @@ -53,7 +53,7 @@ require("../components/time-picker.tag.html"); </button> <div if="{originalFile}" class="original-file {opts.choice.choiceType === 'RESOURCE' ? 'selected' : 'hidden'}"> - <img src="{session.configuration.endPoint}/v1/resources/{originalFile}/preview"/> + <img src="{resourceService.getPreviewUrl(originalFile)}"/> <span> {originalFile.name} <i class="fa fa-remove" @@ -126,6 +126,7 @@ require("../components/time-picker.tag.html"); <script type="es6"> this.session = require("../../js/Session"); + this.resourceService = require("../../js/ResourceService"); let moment = require("moment"); moment.locale(this.session.locale); diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceView.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceView.tag.html index 5c7bd0d5..9cd1dfce 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceView.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/ChoiceView.tag.html @@ -39,7 +39,7 @@ require("../components/MultiLineLabel.tag.html"); </span> <div class="choice-ressource" if={opts.choice.choiceType === "RESOURCE" && meta && isImage(meta)}> - <img class="image-preview" src="{session.configuration.endPoint}/v1/resources/{opts.choice.choiceValue}/preview"/> + <img class="image-preview" src="{resourceService.getPreviewUrl(opts.choice.choiceValue)}"/> </div> <div class="choice-ressource" if={opts.choice.choiceType === "RESOURCE" && meta && !isImage(meta)}> @@ -92,13 +92,13 @@ require("../components/MultiLineLabel.tag.html"); </div> <script type="es6"> - let ResourceService = require("../../js/ResourceService"); this.session = require("../../js/Session"); + this.resourceService = require("../../js/ResourceService"); this.installBundle(this.session, "choice"); this.showModalImage = false; if (this.opts.choice.choiceType === "RESOURCE") { - ResourceService.getMeta(this.opts.choice.choiceValue).then(meta => { + this.resourceService.getMeta(this.opts.choice.choiceValue).then(meta => { this.meta = meta; this.update(); }); diff --git a/pollen-ui-riot-js/src/main/web/tag/poll/PollCard.tag.html b/pollen-ui-riot-js/src/main/web/tag/poll/PollCard.tag.html index b70f2bca..fb5cd606 100644 --- a/pollen-ui-riot-js/src/main/web/tag/poll/PollCard.tag.html +++ b/pollen-ui-riot-js/src/main/web/tag/poll/PollCard.tag.html @@ -18,6 +18,7 @@ along with this program. If not, see <http://www.gnu.org/licenses/>. #L% --> +require("../components/Avatar.tag.html"); <PollCard class="poll-{opts.poll.status.toLowerCase()}"> <div class="card-actions"> @@ -48,7 +49,7 @@ </div> <div class="poll-creator" title={opts.poll.creatorName}> - <LetterAvatar name={opts.poll.creatorName} rounded="true"/> + <Avatar avatar={opts.poll.creatorAvatar} name={opts.poll.creatorName} rounded="true"/> <div class="creator-name"> {opts.poll.creatorName} <div class="creation-date"> -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
This is an automated email from the git hooks/post-receive script. New commit to branch feature/28_avatars in repository pollen. See https://gitlab.nuiton.org/chorem/pollen.git commit 350108b48a96f0a707008da0f8d2d78aa21aaf9c Author: Kevin Morin <morin@codelutin.com> Date: Fri Sep 29 10:02:28 2017 +0200 ajout e variable dans le package.json --- pollen-ui-riot-js/package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pollen-ui-riot-js/package.json b/pollen-ui-riot-js/package.json index 68ec61e0..229fb8dc 100644 --- a/pollen-ui-riot-js/package.json +++ b/pollen-ui-riot-js/package.json @@ -24,7 +24,7 @@ } ], "scripts": { - "start": "webpack-dev-server --hot --inline --host 0.0.0.0 --public localhost:8080", + "start": "webpack-dev-server --hot --inline --host 0.0.0.0 --public ${POLLEN_UI_CONTEXT:-localhost:8080}", "package": "webpack --bail" }, "devDependencies": { -- To stop receiving notification emails like this one, please contact chorem.org SCM administrator <admin+scm@chorem.org>.
participants (1)
-
chorem.org scm