Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add social profile links #5439

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

nertc
Copy link
Contributor

@nertc nertc commented Dec 23, 2024

This PR addresses "Please make contact information fields, how to contact the user, email address, telegrams, various social networks https://www.openstreetmap.org" issue mentioned in the #2245

Description

This PR adds:

  • DB: Social links table, which contains social links added by the user
  • Model: Parser to differentiate different kind of websites
  • Controller: Logic for CRUD operations for social links
  • View: Functionality to show, edit, add and delete social links
  • JS: Was only used for adding and removing fields on the user side when they interact to the social links fields

Currently parser parses these websites and adds their icons which are taken from Bootstrap-Icons:

  • Discord
  • Facebook
  • Github
  • Gitlab
  • Instagram
  • Linkedin
  • Line
  • Mastodon
  • Medium
  • Quora
  • Reddit
  • Skype
  • Slack
  • Snapchat
  • Stack Overflow
  • Strava
  • Substack
  • Telegram
  • Threads
  • Tik-Tok
  • Twitch
  • X (Twitter)
  • Vimeo
  • WhatsApp
  • YouTube

Discord, Line, Skype and Slack doesn't show username in the URL. To avoid showing some Id numbers on the profile page, for these cases instead of the Id only the name of the application is shown.
Applications other than those mentioned in the list show their URL on the profile page and have general web icon (globe icon).
If there is an idea that some of them should be removed or others should be added, feel free to share recommendations.

Parser was done in the Ruby to avoid adding more JS client-side logic to the website. If it is preferable, it can be moved to JS.

How has this been tested?

There are validation and functional tests written to test the functionality. In addition to this, different kind of manual testing was done to ensure that all the icons, errors, fields and etc. were displayed correctly.

Screenshots

Logged out:
image
image

Logged in:
image

Edit Profile page:
image
image

@nertc nertc mentioned this pull request Dec 23, 2024
5 tasks
@nertc nertc force-pushed the issue_2245_add_social_links branch 2 times, most recently from 46f7da6 to 55c89e6 Compare December 24, 2024 07:08
@nertc nertc marked this pull request as ready for review December 24, 2024 07:19
@AntonKhorev
Copy link
Collaborator

Do we need another set of icons in addition to app/assets/images/social_icons?


def parsed
URL_PATTERNS.each do |platform, pattern|
username = url.match(pattern)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's not a username, is it?

Copy link
Contributor Author

@nertc nertc Dec 27, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It's a user's name shown in the URL of some websites' profile page (for example, in the https://github.com/nertc nertc is a username)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

MatchData object is not a username.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

To use more intuitive name and not to confuse "user's name" to username, name of the variable username was changed to names

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is it more intuitive? Now it suggests there are multiple names in this variable.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It is named names, because it will either be null or array that will contain one element (user's name). Naming it name would cause to interpret it as a string or other single object variable, while naming it names emphasizes that it is an array that contains a name of the user.

`);

socialLinkForm.find("button").click(function () {
$(this).parent().remove();
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I press this button, this removes the link, and I'd think it's saved. But actually not, failing the validation will resurrect the link.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

On document load now application checks and hides those fields that have "_destroy" checkbox checked. Therefore, this problem was solved.

@AntonKhorev
Copy link
Collaborator

When I'm making a site for myself and there's this kind of UI with Add buttons adding an input and Remove buttons next to added inputs, I don't bother doing it. I just put a <textarea>, it's easier to edit. In this case I'd have a textarea with each nonempty line corresponding to a link. Why don't people do this? Is it too geeky?

@nertc
Copy link
Contributor Author

nertc commented Jan 8, 2025

When I'm making a site for myself and there's this kind of UI with Add buttons adding an input and Remove buttons next to added inputs, I don't bother doing it. I just put a <textarea>, it's easier to edit. In this case I'd have a textarea with each nonempty line corresponding to a link. Why don't people do this? Is it too geeky?

Thanks for the review. I agree with you, if I did a website only for me, it would be a quicker solution to add a textarea and it would do the job. But for most users current solution will be more intuitive and appealing in terms of UI/UX. It's more common and therefore understandable approach (for example GitHub has the same approach on the profile page).

@nertc
Copy link
Contributor Author

nertc commented Jan 8, 2025

Do we need another set of icons in addition to app/assets/images/social_icons?

They have different design. They are more colorful and more like logos which should gain users' attention (for example as share buttons), but icons added by this PR are one color, simple icons, which should not gain much attention as they are there only for the information for the small part of the profile page (not big functional buttons). We can use icons from the app/assets/images/social_icons, but it will make social profile links too colorful and too much attention grabbing. Therefore, I think, it is better to stick to the new icons.

@nertc nertc force-pushed the issue_2245_add_social_links branch 2 times, most recently from a1b03f9 to bfa37a0 Compare January 8, 2025 10:53
@nertc nertc force-pushed the issue_2245_add_social_links branch 2 times, most recently from dc9d0cb to 8263827 Compare January 27, 2025 09:41
@nertc
Copy link
Contributor Author

nertc commented Jan 27, 2025

Merge conflict was fixed.

<div class="social-link-fields row mb-3">
<%= social_link_form.text_field :url, :hide_label => true, :wrapper_class => "col-sm-8" %>
<%= social_link_form.check_box :_destroy, :wrapper_class => "d-none social_link_destroy" %>
<%= social_link_form.label :_destroy, t(".social_links.remove"), :class => "btn btn-outline-primary col-sm-1 align-self-start" %>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

col-sm-1 is too narrow

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It was changed to col-sm-2. Increasing button's width further will make it too wide.

class SocialLink < ApplicationRecord
belongs_to :user

validates :url, :format => { :with => %r{\Ahttps?://.+\z}, :message => I18n.t("profiles.edit.social_links.http_parse_error") }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

model is referring to controller's i18n key here

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was fixed with the key that is translated outside of the model.

@@ -40,6 +40,21 @@
</div>
</fieldset>

<fieldset class="mb-3">
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why is the link editor placed between avatar and home location? If you don't change the order of other things on this page, this place makes the least sense to me.

Copy link
Contributor Author

@nertc nertc Feb 6, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where do you think is a good place for it? Should it be between the description and avatar, before the description or the last one?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Editor of the social links was moved below the description, as, I think, description has higher priority and should be displayed higher in the editor, and also social links are positioned next to the description and, therefore, in the editor too, social links should be next to the description.

Comment on lines 2 to 7
<p class="text-body-secondary">
<%= image_tag "/assets/social_link_icons/#{social_link.parsed[:platform].nil? ? 'other' : social_link.parsed[:platform]}.svg",
:alt => social_link.parsed[:platform].nil? ? "other" : social_link.parsed[:platform],
:class => "me-2" %>
<%= link_to social_link.parsed[:name], social_link.url, :class => "text-body-secondary", :rel => "nofollow me" %>
</p>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You can get line wraps like this, where the text goes below the icon:

image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From now, URL won't wrap and will show ellipses (...) if it doesn't fit.

<div class="my-3">
<%= link_to t(".edit_profile"), edit_profile_path, :class => "btn btn-outline-primary" %>
</div>
<% end %>
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The placement of this button suggests that it leads to editing only the social links. If it actually did, that could have been a good idea, given how many editable things there are already on profile/edit.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I also thought about a separate page or in-place editing for social links, but for consistency, preferred to keep it in the way that everything is done on the profile page. I agree with you about changing general behavior of editing profile page, but, I think, it will be better if we do it as a separate issue and PR and it will change not some part of profile/edit but whole behavior to in-place edit. For now, to avoid any confusion from users about the function of the button, I'll move it to where it was before (under the description block).


def parsed
URL_PATTERNS.each do |platform, pattern|
names = url.match(pattern)
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

matches urls like https://evil.example.com/reddit.com/user/NotRedditor

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

From now it will check whether regex of the websites directly follows to http://www., https://www., http:// or https://.

@nertc nertc force-pushed the issue_2245_add_social_links branch 3 times, most recently from 61ac59c to 922a34e Compare February 12, 2025 13:52
@nertc
Copy link
Contributor Author

nertc commented Feb 12, 2025

PR was updated according to the comments. Also, master was rebased as a base for this branch.

@nertc
Copy link
Contributor Author

nertc commented Feb 12, 2025

Thanks for the review

@nertc nertc force-pushed the issue_2245_add_social_links branch 2 times, most recently from 75cdfa7 to 698c296 Compare February 14, 2025 13:40
:instagram => %r{\Ahttps?://(?:www\.)?instagram\.com/([a-zA-Z0-9._]+)},
:linkedin => %r{\Ahttps?://(?:www\.)?linkedin\.com/in/([a-zA-Z0-9_-]+)},
:line => %r{\Ahttps?://(?:www\.)?line\.me/ti/p/([a-zA-Z0-9_-]+)},
:mastodon => %r{\Ahttps?://(?:www\.)?mastodon\.social/@([a-zA-Z0-9_]+)},
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Once again mastodon is a problem because mastodon.social is just one option, but I'm not sure what the solution is... At the very least en.osm.town should probably be recognised though.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

en.osm.town was added. It will have the same icon as mastodon.social.

@nertc nertc force-pushed the issue_2245_add_social_links branch 4 times, most recently from a2918b5 to 6d3d931 Compare February 17, 2025 15:27
:medium => %r{\Ahttps?://(?:www\.)?medium\.com/@([a-zA-Z0-9_]+)},
:quora => %r{\Ahttps?://(?:www\.)?quora\.com/profile/([a-zA-Z0-9_-]+)},
:reddit => %r{\Ahttps?://(?:www\.)?reddit\.com/user/([a-zA-Z0-9_-]+)},
:skype => %r{\Ahttps?://(?:www\.)?join\.skype\.com/invite/([a-zA-Z0-9_-]+)},
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

www.join.skype.com doesn't exist. Maybe we don't need www everywhere.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

www. was removed from Skype, Slack and WhatsApp invitation links (all three of them were broken if they were used with www.). As I checked, en.osm.town was also broken with www. and, therefore, Mastodon regex was changed to handle that situation accordingly.

Comment on lines 2 to 7
<div class="text-body-secondary d-flex mb-3">
<%= image_tag "social_link_icons/#{social_link.parsed[:platform].nil? ? 'other' : social_link.parsed[:platform]}.svg",
:alt => social_link.parsed[:platform].nil? ? "other" : social_link.parsed[:platform],
:class => "me-2" %>
<%= link_to social_link.parsed[:name], social_link.url, :class => "text-body-secondary d-block text-truncate", :rel => "nofollow me" %>
</div>
Copy link
Collaborator

@AntonKhorev AntonKhorev Feb 17, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What do you think about this?

Suggested change
<div class="text-body-secondary d-flex mb-3">
<%= image_tag "social_link_icons/#{social_link.parsed[:platform].nil? ? 'other' : social_link.parsed[:platform]}.svg",
:alt => social_link.parsed[:platform].nil? ? "other" : social_link.parsed[:platform],
:class => "me-2" %>
<%= link_to social_link.parsed[:name], social_link.url, :class => "text-body-secondary d-block text-truncate", :rel => "nofollow me" %>
</div>
<%= link_to social_link.url, :class => "icon-link mw-100 text-body-secondary mb-3", :rel => "nofollow me" do %>
<%= image_tag "social_link_icons/#{social_link.parsed[:platform].nil? ? 'other' : social_link.parsed[:platform]}.svg",
:alt => social_link.parsed[:platform].nil? ? "other" : social_link.parsed[:platform],
:size => "16" %>
<span class="text-truncate">
<%= social_link.parsed[:name] %>
</span>
<% end %>

This also requires putting links in unstyled list (<ul class="list-unstyled">), but don't you want them to be a list anyway?

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

They are in a list on github for example
image

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the suggestion. It was applied and <div>s were changed with <ul><li> list structure.

}
end
end
{ :platform => nil, :name => url }
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Maybe we should remove http(s):// from "names" of generic urls because the sidebar can get quite narrow and then http(s):// is going to be all you're able to see.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

http(s):// is now removed in the list. I was also thinking about removing www.. What do you think about it?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I always hate if browsers liying about the real url, but here this is probably a good idea.

@nertc nertc force-pushed the issue_2245_add_social_links branch from 6d3d931 to 4189291 Compare February 20, 2025 06:56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants