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

generalize profile links #1524

Open
wants to merge 56 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 9 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
26494ff
checkpoint: created new table, user profile page shows values if pres…
cellio Jan 24, 2025
d95d0e0
less-bad layout
cellio Jan 24, 2025
b2b2593
spacing tweak
cellio Jan 26, 2025
6ef2850
attempting to validate URLs (doesn't work)
cellio Jan 26, 2025
0c3f710
remove redundant form (edits can now be submitted but they don't update)
cellio Jan 26, 2025
afe68b2
put error-handling in correct place
cellio Jan 26, 2025
6ddbe00
make sure we assign response?
cellio Jan 26, 2025
fb0fd7f
comment
cellio Jan 26, 2025
119fac3
minor cleanup (these were probably bugs but not the only ones)
cellio Jan 26, 2025
17a3bde
review feedback
cellio Jan 26, 2025
65e3b71
added some comments
cellio Jan 26, 2025
00c0a01
Merge branch 'develop' into cellio/1248-generalize-profile-links
Oaphi Jan 26, 2025
c7f5dd5
fixed up rubocop errors
Oaphi Jan 26, 2025
c37592e
installed maintenance task gem (see https://github.com/Shopify/mainte…
cellio Jan 28, 2025
32a742a
filter out not-real user_websites
cellio Jan 28, 2025
2a9d3e0
rubocop
cellio Jan 28, 2025
37f8548
need to access the user_websites attrs explicitly
cellio Jan 29, 2025
11a5c89
need both in the permit list
cellio Jan 29, 2025
12ccc61
fixed :user_websites_attributes accessors
Oaphi Jan 29, 2025
8c71e6f
validated_profile_websites should correctly transform values
Oaphi Jan 29, 2025
de877bf
removed no longer needed validate_profile_website
Oaphi Jan 29, 2025
a89c730
temporarily fixed :twitter not being adding to permitted params
Oaphi Jan 29, 2025
d8d7104
removed unnecessary comments
Oaphi Jan 29, 2025
c37f016
'invalid external link' should only be flashed if there actually are …
Oaphi Jan 29, 2025
acaa348
added User#same? method
Oaphi Jan 29, 2025
a38f0e1
validated_profile_websites should only return those params that have …
Oaphi Jan 29, 2025
27979fb
fixed danger notice when some of the user website links are invalid
Oaphi Jan 29, 2025
e80b93d
temporary fix for users_controller tests until twitter/discord is rem…
Oaphi Jan 29, 2025
d35dbd4
switched to maintenance_tasks v2.1.1 (can't test Ruby 2.7.8 on higher…
Oaphi Jan 29, 2025
1a3d4fa
default order so edit page will work right
cellio Jan 29, 2025
2223e5d
simplication: allow anything, only linkify http links, and apply nerf…
cellio Jan 29, 2025
92cd458
catch blank values and convert to nil for DB constraint, and now we n…
cellio Jan 30, 2025
981b92e
removed validated_profile_websites as we don't use it anymore
Oaphi Jan 30, 2025
74926e1
rubocop fix for user model
Oaphi Jan 30, 2025
0169871
remove unused fields from edit form
cellio Jan 30, 2025
5c8b48d
removed unused method
cellio Jan 30, 2025
32428a8
rubocop (someday I will figure out why my editor is adding those utf-…
cellio Jan 30, 2025
4a36962
removed website and twitter sections, moved discord below extra fields
cellio Jan 30, 2025
73dc8b1
removed no longer needed ensure_protocol
Oaphi Jan 30, 2025
e10334d
add CSS classes for mobile
cellio Jan 30, 2025
134e0e0
on login, ensure that the right number of rows in user_websites exists
cellio Jan 31, 2025
d6b4e6c
really, rubocop? screaming constants? SHOUTING IS RUDE :-P
cellio Jan 31, 2025
ac5ad73
oh, *that's* how you attach it to user creation! (moved ensure call)
cellio Jan 31, 2025
20e3810
renamed User#same? method to User#same_as?
Oaphi Feb 1, 2025
3a663c0
fixed up newly introduced tab stops
Oaphi Feb 1, 2025
afacd50
'present? or nil' is exactly what 'presence' does
Oaphi Feb 1, 2025
ca1d60a
test for fixing the pipeline
Oaphi Feb 1, 2025
c28a253
Revert "test for fixing the pipeline"
Oaphi Feb 1, 2025
23c1a02
removed unnecessary comments from user websites maintenance tasks & e…
Oaphi Feb 1, 2025
704feaa
user_id is implicit when accessing user.user_websites
Oaphi Feb 1, 2025
a152b4a
update user controller test to remove website/twitter, add discord
cellio Feb 2, 2025
d766380
where().size.positive? can be shortened to exists?(<conditions>)
Oaphi Feb 2, 2025
2d52f7e
UsersController#update_profile should allow partial updates
Oaphi Feb 2, 2025
720ee8b
split the overloaded update_profile test
Oaphi Feb 2, 2025
4b72f57
add editor test for user_websites
cellio Feb 4, 2025
80db9e9
rubocop
cellio Feb 4, 2025
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 23 additions & 6 deletions app/controllers/users_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -355,9 +355,10 @@ def edit_profile
render layout: 'without_sidebar'
end

# to be deleted (when I'm done debugging with it)
def validate_profile_website(profile_params)
uri = profile_params[:website]

if URI.parse(uri).instance_of?(URI::Generic)
# URI::Generic indicates the user didn't include a protocol, so we'll add one now so that it can be
# parsed correctly in the view later on.
Expand All @@ -368,14 +369,30 @@ def validate_profile_website(profile_params)
flash[:danger] = 'Invalid profile website link.'
end

def update_profile
profile_params = params.require(:user).permit(:username, :profile_markdown, :website, :twitter, :discord)
profile_params[:twitter] = profile_params[:twitter].delete('@')
def validate_profile_websites(profile_params)
sites = profile_params[:user_websites]
sites.all? { |u| u = ensure_protocol(u.url) }
Oaphi marked this conversation as resolved.
Show resolved Hide resolved
end

if profile_params[:website].present?
validate_profile_website(profile_params)
def ensure_protocol(uri)
if URI.parse(uri).instance_of?(URI::Generic)
# URI::Generic indicates the user didn't include a protocol, so we'll add one now so that it can be
# parsed correctly in the view later on.
return "https://#{uri}"
else
return uri
end
rescue URI::InvalidURIError
return nil
end
Oaphi marked this conversation as resolved.
Show resolved Hide resolved

def update_profile
profile_params = params.require(:user).permit(:username, :profile_markdown, :website, :discord, :user_websites)

if profile_params[:user_websites].present?
profile_params[:user_websistes] = validate_profile_websites(profile_params) || flash[:danger] = "Invalid external link"
end

@user = current_user

if params[:user][:avatar].present?
Expand Down
7 changes: 7 additions & 0 deletions app/models/user.rb
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
# coding: utf-8
# Represents a user. Most of the User's logic is controlled by Devise and its overrides. A user, as far as the
# application code (i.e. excluding Devise) is concerned, has many questions, answers, and votes.
class User < ApplicationRecord
Expand Down Expand Up @@ -27,6 +28,8 @@ class User < ApplicationRecord
has_many :comment_threads_locked, class_name: 'CommentThread', foreign_key: :locked_by_id, dependent: :nullify
has_many :category_filter_defaults, dependent: :destroy
has_many :filters, dependent: :destroy
has_many :user_websites, dependent: :destroy
accepts_nested_attributes_for :user_websites
belongs_to :deleted_by, required: false, class_name: 'User'

validates :username, presence: true, length: { minimum: 3, maximum: 50 }
Expand Down Expand Up @@ -130,6 +133,10 @@ def website_domain
website.nil? ? website : URI.parse(website).hostname
end

def websites_for
user_websites.order(position)
end

def is_moderator
is_global_moderator || community_user&.is_moderator || is_admin || community_user&.privilege?('mod') || false
end
Expand Down
5 changes: 5 additions & 0 deletions app/models/user_website.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
class UserWebsite < ApplicationRecord

belongs_to :user

cellio marked this conversation as resolved.
Show resolved Hide resolved
end
18 changes: 18 additions & 0 deletions app/views/users/edit_profile.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,24 @@
<p>Note: Links are not shown publicly until you have earned the Participate Everywhere ability.</p>
<div class="post-preview"></div>

<div>
<p>External links (your web site, blog, social media, GitHub, etc)</p>
ArtOfCode- marked this conversation as resolved.
Show resolved Hide resolved
<div class="grid">
<%= f.fields_for :user_websites do |w| %>
<div class="grid grid--cell is-12">
<div class="grid grid--cell is-4">
<div class="grid--cell is-2">Label:</div>
<div class="grid--cell is-10"><%= w.text_field :label, class: 'form-element' %></div>
</div>
<div class="grid grid--cell is-6">
<div class="grid--cell is-1">URL:</div>
<div class="grid--cell is-11"><%= w.text_field :url, class: 'form-element' %></div>
</div>
</div>
<% end %>
</div>
</div>

<div class="grid">
<div class="grid--cell is-4 is-12-sm form-group">
<%= f.label :website, class: "form-element" %>
Expand Down
14 changes: 14 additions & 0 deletions app/views/users/show.html.erb
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,20 @@
<% end %>
</div>

<% if @user.user_websites.size > 0 %>
<div>
<p><strong>External links</strong></p>
<table class="table is-with-hover">
<% @user.user_websites.first(3).each do |w| %>
<tr>
<td><%= w.label %></td>
<td><%= link_to w.url, w.url, rel: 'nofollow' %></td>
</tr>
<% end %>
</table>
cellio marked this conversation as resolved.
Show resolved Hide resolved
</div>
<% end %>

<div class="button-list h-p-2">
<% if user_signed_in? %>
<%= link_to new_subscription_path(type: 'user', qualifier: @user.id, return_to: request.path), class: "button is-outlined is-small" do %>
Expand Down
11 changes: 11 additions & 0 deletions db/migrate/20250123141400_create_user_websites.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
class CreateUserWebsites < ActiveRecord::Migration[7.0]
def change
create_table :user_websites do |t|
t.column :label, :string, limit:80
t.string :url
t.integer :position
end
add_reference :user_websites, :user, null: false, foreign_key: true
add_index(:user_websites, [:user_id, :url], unique: true)
end
end
12 changes: 11 additions & 1 deletion db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema[7.0].define(version: 2024_10_20_193053) do
ActiveRecord::Schema[7.0].define(version: 2025_01_23_141400) do
create_table "abilities", charset: "utf8mb4", collation: "utf8mb4_0900_ai_ci", force: :cascade do |t|
t.bigint "community_id"
t.string "name"
Expand Down Expand Up @@ -684,6 +684,15 @@
t.index ["community_user_id"], name: "index_user_abilities_on_community_user_id"
end

create_table "user_websites", charset: "utf8mb4", collation: "utf8mb4_unicode_ci", force: :cascade do |t|
t.string "label", limit: 80
t.string "url"
t.integer "position"
t.bigint "user_id", null: false
t.index ["user_id", "url"], name: "index_user_websites_on_user_id_and_url", unique: true
t.index ["user_id"], name: "index_user_websites_on_user_id"
end

create_table "users", charset: "utf8mb4", collation: "utf8mb4_unicode_ci", force: :cascade do |t|
t.string "email"
t.string "encrypted_password"
Expand Down Expand Up @@ -826,6 +835,7 @@
add_foreign_key "thread_followers", "posts"
add_foreign_key "user_abilities", "abilities"
add_foreign_key "user_abilities", "community_users"
add_foreign_key "user_websites", "users"
add_foreign_key "users", "users", column: "deleted_by_id"
add_foreign_key "votes", "communities"
add_foreign_key "warning_templates", "communities"
Expand Down
Loading