-
Notifications
You must be signed in to change notification settings - Fork 12
Conversation
473cbfb
to
73cfc9b
Compare
PR still WIP but updated. User profile with no geometry (=> no map): User profile with geometry (but no content): Despite what is suggested in #335 (comment)
I have chosen to make the UI service return a JSON response instead of an HTML response. I wanted to avoid the problem we have with the preview service: angular code seems to be not executed in HTML code returned asynchronously. See #168 (comment) The JSON data are then rendered using angular expressions. There are several problems remaining though:
|
I would be great to use the design that was planned for the profiles (with the nice banner image at the top): |
That's a problem we have to solve anyway. This should not be an argument to do it differently for the profile. |
What nice banner image? The rest of the page is completely irrelevant here: it's the user's prefs UI, which is another page. |
You are merciless :P |
For the long term it would be nice that the user can upload their own banner image. But for now a default image would already be good. Or a random image out of 3-5. Maybe @ginold can do some magic here like for the homepage? :)
But the header is the same for the profile page. |
:D Sorry, but you self are saying:
|
It does not make sense to display a dummy image (that would be the same for every one or a random one not even chosen by the user). And we simply don't have time for this. |
It would make the page look better... |
For sure! But if the user cannot choose their own image (and we don't have time for this), they won't be happy with it. So it's better to have no image in the meantime. Honestly we already have enough troubles with this page... |
I think differently about this.
Then let's first take care of these troubles and we can discuss the banner image again once they are solved. |
+1 for the image banner! it adds so much to the page. The not-logged user page looks so much nicer with an image - could we use the same image for everyone for now (the one that is found on the mock-ups) ? ...when the troubles are solved :P |
I have the feeling that the current way this page is built (with an additional request to the API to add the content - whether returning HTML or JSON) is a bit too complicated and might cause problems, for instance to inject the additional HTML or make the additional angular code be executed (see the problems with the preview service). I wonder if we could not use the standard way to generate a document detail view. The tricky thing is to manage the case where the profile page is not public.
This way we could keep the usual way of generating a document detail view page, with the usual tools => no problem to integrate the map info or the other additional content. What do you think? |
The browser makes the request, so you can not set custom headers.
How would that work? |
If I knew I wouldn't ask :P |
Perhaps it could be done like this:
Perhaps we should also consider making newly created profile pages (for new registered users) public by default. An other approach:
|
Why not always do it like this? Currently only 7% of the profiles are public. Why make it more complex for a less common case?
This should be up to the user to decide. Information that was private in v5 should also be private in v6. |
To do what? Passing the JWT token? Or perhaps I don't understand your point, could you precise? |
I understood that you are talking about the original idea as described here: #335 |
No, as I said the original idea is also complicated and not that easy to implement.
I suggested that the controller in the "fallback page" would reload the full page (not make an asynchronous request to load a part of the page as currently) and pass the JWT token.
|
f819b32
to
6a2ad19
Compare
I'm having a hard time trying to recenter the map on the user's geometry (if any). The tricky thing is to pass the user feature to the map directive. For other point document it is done by setting the With the user profiles, it's a bit more complicated because the profile data (including the geometry) are retrieved AFTER the initial page has been generated (with the default When the profile data are returned as some additional HTML code plugged and compiled in some place of the initial page, a map directive is actually added and rendered. But I still need to find a way to pass the geometry (most likely in a featureCollection as for the other document types). I have tried to redefined the module value in the additional HTML code:
but for some reason the map directive always receive the initial I have then tried to pass the feature collection as an additional map directive attribute I have eventually tried this solution (using an expression to save the feature collection to a scope element): afd713e
I had a similar error in debug mode before adding the one-time binding operator Tips very much welcome :) |
Another complication: it seems that it's not possible to directly call controllers (ignored? not defined?) from the HTML added asynchronously in the profile page. For instance tooltip translating as in
or checking the user permissions before showing the floating buttons (edit, add images, etc.):
do not work. On the other hand, directives (eg. map) seem to be taken into account as expected. |
To limit this problem, 5fe23f1 adds the minimal data (eg. user name) to the base profile page (+ makes this page cached). The next step is to transfer the editing buttons to this base page (the additional HTML then containing only the actual user infos), this way controllers will be available. |
See 7abbc1a |
e43907c
to
c3c192f
Compare
168998e
to
1d76df5
Compare
This PR can now be reviewed. I am not sure profile images are correctly shown in the profiles. It seems the API does not return them anyway? There a still some styling fixes to do but I will probably need help!
|
The images associated to a user profile are returned with c2corg/v6_api#439. Please make sure your API instance is up-to-date. |
I will try to fix your css issues. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Thanks, that is looking good!
Maybe @ginold can take a look at the HTML/CSS part?
class="float-button float-followed" tooltip-placement="left" | ||
uib-tooltip="{{'No longer follow' | translate}}"> | ||
<span class="glyphicon glyphicon-star"></span> | ||
<p class="float-button-text" translate>No longer follow</p> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe as text: "Unfollow"
And as tooltip: "Stop following this user" ?
(that's how it is on Twitter)
|
||
<div ng-hide="followCtrl.followed" ng-click="followCtrl.toggle()" | ||
class="float-button float-notfollowed" tooltip-placement="left" | ||
uib-tooltip="{{'Follow' | translate}}"> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe as tooltip: "See the activity of this user in your feed" or "See notifications for this user"?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Your suggestion make sense.
But isn't it more consistent with the other tooltip to write "Follow this user" (or "contributor"). I agree that your suggestions are more explicit.
In twitter the buttons are (in french) "Abonné", "S'abonner", "Se désabonner". Perhaps "Subscribe" in english?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps "Subscribe" in english?
In English it's "Follow/Unfollow". Maybe it's not clear to every user what "following a user" means.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In English in Twitter it's "Follow", "Unfollow", "Following" and there's no tooltip.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe it's not clear to every user what "following a user" means.
OK I will use "See the activity of this contributor in your feed"
|
||
var config = { | ||
headers: { | ||
'Accept': 'application/json' |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is this header required?
var url = '/profiles/data/{id}/{lang}' | ||
.replace('{id}', this.userId.toString()) | ||
.replace('{lang}', this.lang); | ||
var promise = $http.get(url, config); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe add a comment:
"An authenticated request is made to the ui server to get the profile data as rendered HTML (profiles can be marked as non-public)"
@@ -26,7 +26,7 @@ <h4 class="text-success text-center" translate ng-show="feedCtrl.busy">Loading f | |||
|
|||
<p class="action-line"> | |||
<span class="action" ng-cloak> | |||
<b><a ng-href="todo">{{doc['user']['name']}}</a></b> | |||
<b><a ng-href="/profiles/{{doc['user']['document_id']}}/{{doc['user']['locales'][0]['lang']}}">{{doc['user']['name']}}</a></b> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
{{doc['user']['locales'][0]['lang']}}
I opened a ticket on the API (c2corg/v6_api#423) because I thought that you would not need the locales of a user profile when getting a user in the listing version. But the way you are doing it here, means that you actually need the locale, right?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yes, or at least the available_langs
of the profile
@@ -20,7 +20,7 @@ <h2 class="text-center">${title}</h2><br> | |||
<a href="${request.route_url( | |||
module + '_archive', id=document_id, lang=lang, | |||
version=version1['version_id'])}"><span translate>Revision as of</span> {{'${1000 * version1['written_at']}' | date:'medium'}}</a><br/> | |||
<span translate>by</span> <a href="#TODO profile for ${version1['user_id']}">${version1['name']}</a> | |||
<span translate>by</span> <a href="${request.route_url('profiles_view_id', id=version1['user_id'])}">${version1['name']}</a> |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would it make sense to have the user locale here? Like in c2corg_ui/static/partials/feed.html
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Indeed the user locale is not available when retrieving the archived versions I think. That's why I use the "id only" link.
Having the user locale (but not the whole description etc.) would make sense to create the whole profile link.
But it's not very critical ("nice to have") because the "id only" link also works (but triggers additional requests to get the lang when loaded).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ticket for the API is here: c2corg/v6_api#446
view_url = request.route_url(model + 's_view_id_lang', id=id, lang=lang) if updating_doc else '' | ||
index_url = request.route_url(model + 's_index') | ||
if model == 'profile': | ||
view_url = request.route_url(model + 's_view', id=id, lang=lang) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why is this different for profiles?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Because profiles have no slug URLs and no index URLs.
Index URLs might be added later.
@@ -313,7 +313,7 @@ <h3 class="heading show-phone outings" ng-click="mainCtrl.animateHeaderIcon($eve | |||
<%def name="get_document_description(locale, doctype)">\ | |||
% if locale.get('summary') or locale.get('description'): | |||
<div class="view-details-description col-xs-12 description"> | |||
% if not doctype == 'article': | |||
% if doctype != 'article' and doctype != 'profile': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
You could write if doctype not in ['article', 'profile']:
(id, lang), cache_document_detail, load_data, render_page, | ||
self._get_cache_key) | ||
|
||
def _get_profile(self, id, lang, old_api_cache_key=None): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Maybe rename this method to _get_profile_info
, because you are not requesting the profile.
_API_ROUTE = 'profiles' | ||
|
||
@view_config(route_name='profiles_view') | ||
def profile(self): |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it would be good to document how the profile page is constructed. Something like:
User profiles are a bit special, because users can mark their profile as non-public so that the profile data has to be requested with an authentication header. The request to get a profile page is made by the browser, so that the authentication header can not be set. That's why the profile page is constructed as follows:
- The browser makes a request
/profiles/123
to the UI server-side (without authentication header). - The UI server sides makes an unauthenticated request to the API to get the available locales of the profile (
api.camptocamp.org/profiles/123/info
) - The UI server-side returns a page containing only the user name.
- On the UI client-side a request is made to the UI server-side to get the profile data as rendered HTML (e.g.
/profiles/data/123/fr
). If the user is logged-in, the request is made authenticated. - The UI server-side makes a request to the API to get the profile data (e.g. (
api.camptocamp.org/profiles/123/fr
)). If the request to the UI server-side was authenticated, the request to the API is also made authenticated. - On the UI client-side the rendered HTML is inserted into the page.
Related to #756, could you please make sure to use relative urls? |
f43db64
to
0d37d11
Compare
I have just rebased/fixed conflicts and pushed the branch again. Most of the comments made by @tsauerwein has been addressed.
|
second branch created because of conflicts : #768 |
Fixes #335
Fixes #640
User profile contains:
QUESTIONS:
have a profile list page (advanced search page)?users/234567/fr
) in addition to v6 URLs (profiles/234567/fr
)? or done with other v5>v6 redirections?