187 lines
5.6 KiB
Ruby
187 lines
5.6 KiB
Ruby
# typed: strict
|
|
module Domain::UsersHelper
|
|
extend T::Sig
|
|
extend T::Helpers
|
|
include HelpersInterface
|
|
abstract!
|
|
|
|
sig do
|
|
params(
|
|
avatar: T.nilable(Domain::UserAvatar),
|
|
thumb: T.nilable(String),
|
|
).returns(String)
|
|
end
|
|
def domain_user_avatar_img_src_path(avatar, thumb: nil)
|
|
if (sha256 = avatar&.log_entry&.response_sha256)
|
|
blob_path(HexUtil.bin2hex(sha256), format: "jpg", thumb: thumb)
|
|
else
|
|
# default / 'not found' avatar image
|
|
# "/blobs/9080fd4e7e23920eb2dccfe2d86903fc3e748eebb2e5aa8c657bbf6f3d941cdc/contents.jpg"
|
|
asset_path("user-circle.svg")
|
|
end
|
|
end
|
|
sig do
|
|
params(
|
|
avatar: T.nilable(Domain::UserAvatar),
|
|
thumb: T.nilable(String),
|
|
).returns(String)
|
|
end
|
|
def domain_user_avatar_img_tag(avatar, thumb: nil)
|
|
if (sha256 = avatar&.log_entry&.response_sha256)
|
|
image_tag(
|
|
blob_path(HexUtil.bin2hex(sha256), format: "jpg", thumb: thumb),
|
|
class: "inline-block h-4 w-4 flex-shrink-0 rounded-sm object-cover",
|
|
alt: avatar&.user&.name_for_view || "user avatar",
|
|
)
|
|
else
|
|
raw <<~SVG
|
|
<svg xmlns="http://www.w3.org/2000/svg" fill="none" viewBox="0 0 24 24" stroke-width="1.5" stroke="currentColor" class="w-4 h-4">
|
|
<path stroke-linecap="round" stroke-linejoin="round" d="M15.75 6a3.75 3.75 0 11-7.5 0 3.75 3.75 0 017.5 0zM4.501 20.118a7.5 7.5 0 0114.998 0A17.933 17.933 0 0112 21.75c-2.676 0-5.216-.584-7.499-1.632z" />
|
|
</svg>
|
|
SVG
|
|
end
|
|
end
|
|
|
|
sig { params(user: Domain::User).returns(String) }
|
|
def site_name_for_user(user)
|
|
case user
|
|
when Domain::User::E621User
|
|
"E621"
|
|
when Domain::User::FaUser
|
|
"Furaffinity"
|
|
when Domain::User::InkbunnyUser
|
|
"Inkbunny"
|
|
else
|
|
Kernel.raise "Unknown user type: #{user.class}"
|
|
end
|
|
end
|
|
|
|
sig { params(user: Domain::User).returns(String) }
|
|
def site_icon_path_for_user(user)
|
|
case user
|
|
when Domain::User::E621User
|
|
asset_path("domain-icons/e621.png")
|
|
when Domain::User::FaUser
|
|
asset_path("domain-icons/fa.png")
|
|
when Domain::User::InkbunnyUser
|
|
asset_path("domain-icons/inkbunny.png")
|
|
else
|
|
Kernel.raise "Unknown user type: #{user.class}"
|
|
end
|
|
end
|
|
|
|
sig { params(user: Domain::User).returns(String) }
|
|
def domain_user_path(user)
|
|
"#{domain_users_path}/#{user.to_param}"
|
|
end
|
|
|
|
sig { returns(String) }
|
|
def domain_users_path
|
|
"/users"
|
|
end
|
|
|
|
sig { params(user: Domain::User).returns(String) }
|
|
def domain_user_posts_path(user)
|
|
"#{domain_user_path(user)}/posts"
|
|
end
|
|
|
|
sig { params(user: Domain::User).returns(String) }
|
|
def domain_user_favorites_path(user)
|
|
"#{domain_user_path(user)}/favorites"
|
|
end
|
|
|
|
class StatRow < T::ImmutableStruct
|
|
include T::Struct::ActsAsComparable
|
|
|
|
const :name, String
|
|
const :value,
|
|
T.nilable(
|
|
T.any(String, Integer, HasTimestampsWithDueAt::TimestampScanInfo),
|
|
)
|
|
const :link_to, T.nilable(String)
|
|
const :fa_icon_class, T.nilable(String)
|
|
const :hover_title, T.nilable(String)
|
|
end
|
|
|
|
sig { params(user: Domain::User).returns(T::Array[StatRow]) }
|
|
def stat_rows_for_user(user)
|
|
rows = T.let([], T::Array[StatRow])
|
|
if user.has_faved_posts?
|
|
rows << StatRow.new(name: "Favorites", value: user.user_post_favs.count)
|
|
end
|
|
if user.has_followed_users?
|
|
rows << StatRow.new(
|
|
name: "Following",
|
|
value: user.user_user_follows_from.count,
|
|
)
|
|
end
|
|
if user.has_followed_by_users?
|
|
rows << StatRow.new(
|
|
name: "Followed by",
|
|
value: user.user_user_follows_to.count,
|
|
)
|
|
end
|
|
|
|
can_view_timestamps = policy(user).view_page_scanned_at_timestamps?
|
|
can_view_log_entries = policy(user).view_log_entries?
|
|
icon_for =
|
|
Kernel.proc do |due_for_scan|
|
|
due_for_scan ? "fa-hourglass-half" : "fa-check"
|
|
end
|
|
|
|
if user.is_a?(Domain::User::FaUser) && can_view_timestamps
|
|
rows << StatRow.new(
|
|
name: "Favs scanned",
|
|
value: user.favs_scan,
|
|
fa_icon_class: icon_for.call(user.favs_scan.due?),
|
|
hover_title: user.favs_scan.interval.inspect,
|
|
)
|
|
rows << StatRow.new(
|
|
name: "Gallery scanned",
|
|
value: user.gallery_scan,
|
|
fa_icon_class: icon_for.call(user.gallery_scan.due?),
|
|
hover_title: user.gallery_scan.interval.inspect,
|
|
)
|
|
rows << StatRow.new(
|
|
name: "Follows scanned",
|
|
value: user.follows_scan,
|
|
fa_icon_class: icon_for.call(user.follows_scan.due?),
|
|
hover_title: user.follows_scan.interval.inspect,
|
|
)
|
|
if can_view_log_entries && hle = user.guess_last_user_page_log_entry
|
|
rows << StatRow.new(
|
|
name: "Page scanned",
|
|
value: user.page_scan,
|
|
link_to: log_entry_path(hle),
|
|
fa_icon_class: icon_for.call(user.page_scan.due?),
|
|
hover_title: user.page_scan.interval.inspect,
|
|
)
|
|
else
|
|
rows << StatRow.new(
|
|
name: "Page scanned",
|
|
value: user.page_scan,
|
|
fa_icon_class: icon_for.call(user.page_scan.due?),
|
|
hover_title: user.page_scan.interval.inspect,
|
|
)
|
|
end
|
|
elsif user.is_a?(Domain::User::E621User) && can_view_timestamps
|
|
if user.favs_are_hidden
|
|
rows << StatRow.new(name: "Favorites hidden", value: "yes")
|
|
else
|
|
rows << StatRow.new(
|
|
name: "Server favorites",
|
|
value: user.num_other_favs_cached,
|
|
)
|
|
end
|
|
rows << StatRow.new(
|
|
name: "Favorites scanned",
|
|
value: user.favs_scan,
|
|
fa_icon_class: icon_for.call(user.favs_scan.due?),
|
|
hover_title: user.favs_scan.interval.inspect,
|
|
)
|
|
end
|
|
|
|
rows
|
|
end
|
|
end
|