primitive profile page

This commit is contained in:
byte[] 2019-11-11 20:27:09 -05:00
parent a0e08f49c3
commit c13c43aaf2
25 changed files with 182 additions and 28 deletions

View file

@ -13,7 +13,8 @@ config :philomena,
password_pepper: "dn2e0EpZrvBLoxUM3gfQveBhjf0bG/6/bYhrOyq3L3hV9hdo/bimJ+irbDWsuXLP",
otp_secret_key: "Wn7O/8DD+qxL0X4X7bvT90wOkVGcA90bIHww4twR03Ci//zq7PnMw8ypqyyT/b/C",
image_url_root: "/img",
avatar_url_root: "/avatars"
avatar_url_root: "/avatars",
badge_url_root: "/media"
config :philomena, :pow,
user: Philomena.Users.User,

View file

@ -20,6 +20,7 @@ config :philomena,
avatar_url_root: System.get_env("AVATAR_URL_ROOT"),
otp_secret_key: System.get_env("OTP_SECRET_KEY"),
image_url_root: System.get_env("IMAGE_URL_ROOT"),
badge_url_root: System.get_env("BADGE_URL_ROOT"),
camo_host: System.get_env("CAMO_HOST"),
camo_key: System.get_env("CAMO_KEY"),
cdn_host: System.get_env("CDN_HOST")

View file

@ -54,6 +54,9 @@ defimpl Canada.Can, for: [Atom, Philomena.Users.User] do
def can?(_user, :show, %Forum{access_level: "normal"}), do: true
def can?(_user, :show, %Topic{hidden_from_users: false}), do: true
# View profile pages
def can?(_user, :show, %User{}), do: true
# Otherwise...
def can?(_user, _action, _model), do: false
end

View file

@ -11,7 +11,15 @@ defmodule Philomena.Users.User do
import Ecto.Changeset
@derive {Phoenix.Param, key: :slug}
schema "users" do
has_many :links, Philomena.Users.Link
has_many :verified_links, Philomena.Users.Link, where: [aasm_state: "verified"]
has_many :public_links, Philomena.Users.Link, where: [public: true, aasm_state: "verified"]
has_many :galleries, Philomena.Galleries.Gallery
has_many :awards, Philomena.Badges.Award
belongs_to :current_filter, Philomena.Filters.Filter
belongs_to :deleted_by_user, Philomena.Users.User

View file

@ -0,0 +1,54 @@
defmodule PhilomenaWeb.ProfileController do
use PhilomenaWeb, :controller
alias Philomena.{Images, Images.Image, Comments.Comment, Posts.Post, Users.User, Users.Link}
alias Philomena.Repo
import Ecto.Query
plug :load_and_authorize_resource, model: User, only: :show, id_field: "slug", preload: [awards: :badge, public_links: :tag]
def show(conn, _params) do
current_user = conn.assigns.current_user
filter = conn.assigns.compiled_filter
user = conn.assigns.user
{:ok, upload_query} = Images.Query.compile(current_user, "uploader_id:#{user.id}")
{:ok, fave_query} = Images.Query.compile(current_user, "faved_by_id:#{user.id}")
recent_uploads =
Image.search_records(
%{
query: %{
bool: %{
must_not: filter,
must: upload_query
}
}
},
%{page_number: 1, page_size: 6},
Image |> preload([:tags])
)
recent_faves =
Image.search_records(
%{
query: %{
bool: %{
must_not: filter,
must: fave_query
}
}
},
%{page_number: 1, page_size: 6},
Image |> preload([:tags])
)
render(
conn,
"show.html",
user: user,
recent_uploads: recent_uploads,
recent_faves: recent_faves
)
end
end

View file

@ -39,6 +39,7 @@ defmodule PhilomenaWeb.Router do
resources "/current", CurrentController, only: [:update], singular: true
end
resources "/filters", FilterController
resources "/profiles", ProfileController, only: [:show]
get "/:id", ImageController, :show
end

View file

@ -7,6 +7,6 @@
=> @comment.image.id
' by
span.hyphenate-breaks
= render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @comment
= render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @comment, conn: @conn
br
= pretty_time(@comment.created_at)

View file

@ -3,7 +3,7 @@
i.fa.fa-thumbtack>
= if @topic.last_post do
span.hyphenate-breaks
= render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @topic.last_post
= render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @topic.last_post, conn: @conn
' replied to
/=> link_to 'replied to', short_topic_post_path(topic.forum, topic, topic.last_post, anchor: "post_#{topic.last_post.id}") TODO
=> @topic.title

View file

@ -3,7 +3,7 @@
= if @featured_image do
.center
h4.remove-top-margin Featured Image
= render PhilomenaWeb.ImageView, "_image_box.html", image: @featured_image, size: :medium
= render PhilomenaWeb.ImageView, "_image_box.html", image: @featured_image, size: :medium, conn: @conn
.block.block--fixed.block--fixed--sub.block--success.center.hide-mobile
' Enjoy the site?
a href="/pages/donations"
@ -16,24 +16,24 @@
' Trending Images
.block__content.flex.flex--centered.flex--wrap.image-flex-grid
= for image <- @top_scoring do
= render PhilomenaWeb.ImageView, "_image_box.html", image: image, size: :thumb_small
= render PhilomenaWeb.ImageView, "_image_box.html", image: image, size: :thumb_small, conn: @conn
a.block__header--single-item.center href="/search?q=*&sf=score&sd=desc"
' All Time Top Scoring
.block.hide-mobile
a.block__header--single-item.center href="/channels"
' Streams
= for channel <- @streams do
= render PhilomenaWeb.ActivityView, "_channel_strip.html", channel: channel
= render PhilomenaWeb.ActivityView, "_channel_strip.html", channel: channel, conn: @conn
.block.hide-mobile
a.block__header--single-item.center href="/forums"
' Forum Activity
= for topic <- @topics do
= render PhilomenaWeb.ActivityView, "_topic_strip.html", topic: topic
= render PhilomenaWeb.ActivityView, "_topic_strip.html", topic: topic, conn: @conn
.block.hide-mobile
a.block__header--single-item.center href="/lists/recent_comments"
' Recent Comments
= for comment <- @comments do
= render PhilomenaWeb.ActivityView, "_comment_strip.html", comment: comment
= render PhilomenaWeb.ActivityView, "_comment_strip.html", comment: comment, conn: @conn
a.block__header--single-item.center href="/search?q=first_seen_at.gt:3 days ago&sf=comments&sd=desc"
' Most Commented-on Images

View file

@ -1,9 +1,9 @@
article.block.communication id="comment_#{@comment.id}"
.block__content.flex.flex--no-wrap
.flex__fixed.spacing-right
= render PhilomenaWeb.UserAttributionView, "_anon_user_avatar.html", object: @comment
= render PhilomenaWeb.UserAttributionView, "_anon_user_avatar.html", object: @comment, conn: @conn
.flex__grow.communication__body
span.communication__body__sender-name = render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @comment
span.communication__body__sender-name = render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @comment, conn: @conn
.communication__body__text
/- if comment.hidden_from_users
/ strong.comment_deleted
@ -23,7 +23,7 @@ article.block.communication id="comment_#{@comment.id}"
.block__content.communication__options
.flex.flex--wrap.flex--spaced-out
= render PhilomenaWeb.CommentView, "_comment_options.html", comment: @comment
= render PhilomenaWeb.CommentView, "_comment_options.html", comment: @comment, conn: @conn
/- if can?(:hide, Comment)
/ .js-staff-action
/ - if !comment.hidden_from_users && !comment.destroyed_content

View file

@ -5,7 +5,7 @@
= if @filter.user do
p
' Maintained by
= render PhilomenaWeb.UserAttributionView, "_user.html", object: @filter
= render PhilomenaWeb.UserAttributionView, "_user.html", object: @filter, conn: @conn
' .
.filter-options

View file

@ -30,7 +30,7 @@ h1
= if @filter.user do
p.filter-maintainer
' This filter is maintained by
= render PhilomenaWeb.UserAttributionView, "_user.html", object: @filter
= render PhilomenaWeb.UserAttributionView, "_user.html", object: @filter, conn: @conn
' .
p.filter-description

View file

@ -28,6 +28,6 @@ h1 Discussion Forums
br
=> link("Go to post", to: Routes.forum_topic_path(@conn, :show, forum, forum.last_post.topic, post_id: forum.last_post.id) <> "#post_#{forum.last_post.id}")
' by
=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: forum.last_post
=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: forum.last_post, conn: @conn
br
=> pretty_time(forum.last_post.created_at)

View file

@ -41,14 +41,14 @@ h1 = @forum.name
' Posted
=> pretty_time(topic.created_at)
' by
= render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: topic
= render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: topic, conn: @conn
td.table--communication-list__stats.hide-mobile = topic.view_count
td.table--communication-list__stats.hide-mobile = topic.post_count
td.table--communication-list__last-post
= if topic.last_post do
=> link("Go to post", to: Routes.forum_topic_path(@conn, :show, @forum, topic, post_id: topic.last_post) <> "#post_#{topic.last_post.id}")
' by
= render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: topic.last_post
= render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: topic.last_post, conn: @conn
br
=> pretty_time(topic.last_post.created_at)
.block__header.block__header--light

View file

@ -51,7 +51,7 @@
' Uploaded
=> pretty_time(@image.created_at)
' by
=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @image
=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @image, conn: @conn
span.image-size
| &nbsp;
= @image.image_width

View file

@ -1,5 +1,5 @@
= render PhilomenaWeb.ImageView, "_image_meta.html", image: @image
= render PhilomenaWeb.ImageView, "_image_page.html", image: @image
= render PhilomenaWeb.ImageView, "_image_meta.html", image: @image, conn: @conn
= render PhilomenaWeb.ImageView, "_image_page.html", image: @image, conn: @conn
.layout--narrow
.image-description
@ -10,7 +10,7 @@
== @description
.js-tagsauce id="image_tags_and_source_#{@image.id}"
.tagsauce
= render PhilomenaWeb.TagView, "_tag_list.html", tags: display_order(@image.tags)
= render PhilomenaWeb.TagView, "_tag_list.html", tags: display_order(@image.tags), conn: @conn
.block
.flex.flex--wrap#image-source
= if !!@image.source_url and @image.source_url != "" do
@ -21,4 +21,4 @@
h4 Comments
#comments data-current-url="" data-loaded="true"
= for {comment, body} <- @comments do
= render PhilomenaWeb.CommentView, "_comment.html", comment: comment, body: body
= render PhilomenaWeb.CommentView, "_comment.html", comment: comment, body: body, conn: @conn

View file

@ -1,9 +1,9 @@
article.block.communication id="post_#{@post.id}"
.block__content.flex.flex--no-wrap
.flex__fixed.spacing-right
= render PhilomenaWeb.UserAttributionView, "_anon_user_avatar.html", object: @post
= render PhilomenaWeb.UserAttributionView, "_anon_user_avatar.html", object: @post, conn: @conn
.flex__grow.communication__body
span.communication__body__sender-name = render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @post
span.communication__body__sender-name = render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @post, conn: @conn
.communication__body__text
= if !@post.hidden_from_users do
==<> @body

View file

@ -0,0 +1,9 @@
.block
.block__header
span.block__header__title = @title
= if assigns[:view_all_path] do
= link("View all", to: assigns[:view_all_path])
.block__content.js-resizable-media-container
= for image <- @images do
= render PhilomenaWeb.ImageView, "_image_box.html", image: image, size: :thumb

View file

@ -0,0 +1,55 @@
.profile-top
.profile-top__avatar
= render PhilomenaWeb.UserAttributionView, "_user_avatar.html", object: %{user: @user}, class: "avatar--125px"
.profile-top__name-and-links
div
h1.profile-top__name-header
= @user.name
| 's profile
span
' Member since
= pretty_time(@user.created_at)
.profile-top__options
ul.profile-top__options__column
li = link("Send message", to: "#")
li = link("Our conversations", to: "#")
li = link("Report this user", to: "#")
ul.profile-top__options__column
li = link("Uploads", to: Routes.search_path(@conn, :index, q: "uploader_id:#{@user.id}"))
li = link("Comments", to: "#")
li = link("Posts", to: "#")
ul.profile-top__options__column
li = link("Favorites", to: Routes.search_path(@conn, :index, q: "faved_by_id:#{@user.id}"))
li = link("Tag changes", to: "#")
li = link("Source changes", to: "#")
.column-layout
.column-layout__left
.block
.block__header
span.block__header__title User Links
= for link <- @user.public_links do
.block__content.alternating-color.break-word
.center
= if link.tag do
.tag_list = render PhilomenaWeb.TagView, "_tag.html", tag: link.tag
= link(link.uri, to: link.uri)
.block
.block__header
span.block__header__title Badges
= for award <- award_order(@user.awards) do
.block__content.flex.flex--centered.flex--center-distributed.alternating-color.no-overflow title=award.label
.flex__grow.center
.badge = badge_image(award.badge, alt: award.label, size: "32")
br
= award.badge_name || badge.title
.flex__grow.center
= pretty_time(award.awarded_on)
.column-layout__main
= render PhilomenaWeb.ProfileView, "_recent_images.html", title: "Recent Uploads", images: @recent_uploads, view_all_path: Routes.search_path(@conn, :index, q: "uploader_id:#{@user.id}")
= render PhilomenaWeb.ProfileView, "_recent_images.html", title: "Recent Favorites", images: @recent_faves, view_all_path: Routes.search_path(@conn, :index, q: "faved_by_id:#{@user.id}")

View file

@ -17,7 +17,7 @@ h1 = @topic.title
= pagination
.flex--fixed.block__header__item
' Started by
=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @topic
=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @topic, conn: @conn
.flex--fixed.block__header__item
' Posted
=< pretty_time(@topic.created_at)

View file

@ -1,5 +1,6 @@
= if !!@object.user and !@object.anonymous do
strong<> = @object.user.name
strong<>
= link(@object.user.name, to: Routes.profile_path(@conn, :show, @object.user))
- else
strong<>
| Background Pony #

View file

@ -1,4 +1,4 @@
= if !!@object.user and !@object.anonymous do
= user_avatar(@object)
= user_avatar(@object, assigns[:class] || "avatar--100px")
- else
= anonymous_avatar(@object)
= anonymous_avatar(@object, assigns[:class] || "avatar--100px")

View file

@ -1,2 +1,3 @@
= if !!@object.user do
strong<>= @object.user.name
strong<>
= link(@object.user.name, to: Routes.profile_path(@conn, :show, @object.user))

View file

@ -0,0 +1,4 @@
= if !!@object.user do
= user_avatar(@object, assigns[:class] || "avatar--100px")
- else
= anonymous_avatar(assigns[:class] || "avatar--100px")

View file

@ -0,0 +1,16 @@
defmodule PhilomenaWeb.ProfileView do
use PhilomenaWeb, :view
def award_order(awards) do
awards
|> Enum.sort_by(&{!&1.badge.priority, &1.awarded_on})
end
def badge_image(badge, options \\ []) do
img_tag(badge_url_root() <> "/" <> badge.image, options)
end
defp badge_url_root do
Application.get_env(:philomena, :badge_url_root)
end
end