mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-23 20:18:00 +01:00
primitive profile page
This commit is contained in:
parent
a0e08f49c3
commit
c13c43aaf2
25 changed files with 182 additions and 28 deletions
|
@ -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,
|
||||
|
|
|
@ -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")
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
54
lib/philomena_web/controllers/profile_controller.ex
Normal file
54
lib/philomena_web/controllers/profile_controller.ex
Normal 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
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
||||
= @image.image_width
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
55
lib/philomena_web/templates/profile/show.html.slime
Normal file
55
lib/philomena_web/templates/profile/show.html.slime
Normal 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}")
|
|
@ -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)
|
||||
|
|
|
@ -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 #
|
||||
|
|
|
@ -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")
|
|
@ -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))
|
|
@ -0,0 +1,4 @@
|
|||
= if !!@object.user do
|
||||
= user_avatar(@object, assigns[:class] || "avatar--100px")
|
||||
- else
|
||||
= anonymous_avatar(assigns[:class] || "avatar--100px")
|
16
lib/philomena_web/views/profile_view.ex
Normal file
16
lib/philomena_web/views/profile_view.ex
Normal 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
|
Loading…
Reference in a new issue