branch feature/28_avatars updated (c7550c51 -> f0692bd5)
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 from c7550c51 refs #28 ajout de l'avatar pour l'utilisateur + possibilité d'en choisir un parmi les providers disponibles new 95718ac2 refs #28 message si avatar non chargé new f0692bd5 refs #28 finalement on stocke l'avatar dans une resource en base meme quand ça vient d'un tiers The 2 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 f0692bd563403b9ab4074f76219f445a678fd572 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 95718ac27083a73e8e48957682dab5cde85d443f Author: Kevin Morin <morin@codelutin.com> Date: Fri Sep 22 10:39:10 2017 +0200 refs #28 message si avatar non chargé Summary of changes: .../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 +- .../org/chorem/pollen/rest/api/v1/AuthApi.java | 1 + .../chorem/pollen/rest/api/v1/FavoriteListApi.java | 2 +- .../java/org/chorem/pollen/rest/api/v1/GtuApi.java | 4 +- .../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 +--- .../resource/ResourceMetaBean.java} | 33 ++- .../bean/{ => resource}/ResourceStreamBean.java | 50 +--- .../chorem/pollen/services/service/GtuService.java | 4 +- .../services/service/PollenResourceService.java | 25 +- .../pollen/services/service/SocialAuthService.java | 30 +- 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 | 318 +++++++++++---------- 26 files changed, 293 insertions(+), 341 deletions(-) delete mode 100644 pollen-persistence/src/main/resources/db/migration/h2/V3_0_0_11__add_avatar.sql create mode 100644 pollen-persistence/src/main/resources/db/migration/h2/V3_0_1_2__add_avatar.sql delete mode 100644 pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_0_11__add_avatar.sql create mode 100644 pollen-persistence/src/main/resources/db/migration/postgresql/V3_0_1_2__add_avatar.sql rename pollen-services/src/main/java/org/chorem/pollen/services/bean/{ResourceMetaBean.java => resource/AbstractResourceBean.java} (55%) rename pollen-services/src/main/java/org/chorem/pollen/services/bean/{ => resource}/GtuMetaBean.java (85%) rename pollen-services/src/main/java/org/chorem/pollen/services/bean/{ => resource}/ResourceFileBean.java (60%) copy pollen-services/src/main/java/org/chorem/pollen/services/{service/mail/PollClosedEmail.java => bean/resource/ResourceMetaBean.java} (56%) rename pollen-services/src/main/java/org/chorem/pollen/services/bean/{ => resource}/ResourceStreamBean.java (65%) -- 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 95718ac27083a73e8e48957682dab5cde85d443f 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 1dbfbd1a..ef14ff99 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") @GET 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 fbde0ab4..b2329977 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/en.json +++ b/pollen-ui-riot-js/src/main/web/i18n/en.json @@ -407,6 +407,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 47f8b0d8..67ee0bdb 100644 --- a/pollen-ui-riot-js/src/main/web/i18n/fr.json +++ b/pollen-ui-riot-js/src/main/web/i18n/fr.json @@ -407,6 +407,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 ada0bdf3..2333ba0e 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 @@ -157,7 +157,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 749ee115..a0fa145b 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 @@ -121,43 +121,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> @@ -177,14 +183,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 f0692bd563403b9ab4074f76219f445a678fd572 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 | 4 +- .../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 +--- .../services/bean/resource/ResourceMetaBean.java | 54 ++++ .../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, 318 insertions(+), 324 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 dec31e1b..9f814048 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 @@ -6,7 +6,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 bd2e4631..a45e1d49 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,7 +1,7 @@ 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 fd44cb39..21272cad 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; @@ -145,4 +146,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 023864c8..053feff6 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 @@ -161,7 +161,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, @@ -173,6 +173,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 85% 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/GtuMetaBean.java index b7126cb4..26724203 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; /** * @author Sylvain Bavencoff - bavencoff@codelutin.com 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/resource/ResourceMetaBean.java b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java new file mode 100644 index 00000000..315f854e --- /dev/null +++ b/pollen-services/src/main/java/org/chorem/pollen/services/bean/resource/ResourceMetaBean.java @@ -0,0 +1,54 @@ +package org.chorem.pollen.services.bean.resource; + +/* + * #%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% + */ + +import org.chorem.pollen.persistence.entity.PollenResource; + +import java.util.Date; + +/** + * Created on 11/07/14. + * + * @author dralagen + */ +public class ResourceMetaBean extends AbstractResourceBean { + + protected Date uploadDate; + + protected ResourceMetaBean() { + super(PollenResource.class); + } + + @Override + public void fromEntity(PollenResource entity) { + super.fromEntity(entity); + setUploadDate(entity.getTopiaCreateDate()); + } + + 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/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 faf481a8..e5a8dad8 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 @@ -6,8 +6,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 da8edb63..438a8074 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 PollenEntityRef<PollenResource> editResource(String resourceId, ResourceFileBean resource) throws InvalidFormException { checkNotNull(resourceId); checkIsNotPersisted(resource); @@ -163,6 +175,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(); @@ -215,7 +232,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 e651320c..80d6eb97 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 @@ -11,18 +11,23 @@ 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.persistence.entity.UserCredentialTopiaDao; 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 org.chorem.pollen.services.service.security.PollenUnauthorizedException; +import java.net.URL; +import java.net.URLConnection; import java.util.ArrayList; import java.util.List; import java.util.Map; @@ -248,21 +253,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 a0fa145b..001ec045 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 @@ -5,163 +5,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> @@ -169,10 +172,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"); @@ -204,7 +207,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")); }); }; @@ -237,7 +240,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) => { @@ -284,10 +287,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>.
participants (1)
-
chorem.org scm