mirror of
https://github.com/philomena-dev/philomena.git
synced 2024-11-27 13:47:58 +01:00
Merge remote-tracking branch 'origin/staff-tools'
This commit is contained in:
commit
2a9cbb0ff0
23 changed files with 1429 additions and 752 deletions
|
@ -24,13 +24,32 @@ module.exports = {
|
|||
sass: {
|
||||
mode: 'native',
|
||||
options: {
|
||||
includePaths: ['css', 'node_modules/font-awesome/scss']
|
||||
includePaths: ['css', 'node_modules/@fortawesome/fontawesome-free/scss']
|
||||
}
|
||||
},
|
||||
copycat: {
|
||||
fonts: ['node_modules/font-awesome/fonts'],
|
||||
fonts: ['node_modules/@fortawesome/fontawesome-free/webfonts'],
|
||||
verbose: false,
|
||||
onlyChanged: true
|
||||
},
|
||||
postcss: {
|
||||
processors: [
|
||||
require('autoprefixer')({
|
||||
overrideBrowserslist: [
|
||||
'last 2 Android versions',
|
||||
'last 2 Chrome versions',
|
||||
'last 2 ChromeAndroid versions',
|
||||
'last 2 Edge versions',
|
||||
'last 1 Explorer version',
|
||||
'last 1 ExplorerMobile versions',
|
||||
'last 2 Firefox versions',
|
||||
'last 2 FirefoxAndroid versions',
|
||||
'last 2 iOS versions',
|
||||
'last 2 Opera versions'
|
||||
],
|
||||
add: true
|
||||
})
|
||||
]
|
||||
}
|
||||
},
|
||||
conventions: {
|
||||
|
|
|
@ -11,8 +11,14 @@
|
|||
|
||||
@import "global";
|
||||
|
||||
@import "../../node_modules/font-awesome/scss/font-awesome.scss";
|
||||
@import "../../node_modules/normalize-scss/sass/_normalize.scss";
|
||||
// Because FA is a SPECIAL SNOWFLAKE.
|
||||
$fa-font-path: "/fonts";
|
||||
|
||||
@import "../../node_modules/@fortawesome/fontawesome-free/scss/fontawesome.scss";
|
||||
@import "../../node_modules/@fortawesome/fontawesome-free/scss/solid.scss";
|
||||
@import "../../node_modules/@fortawesome/fontawesome-free/scss/regular.scss";
|
||||
@import "../../node_modules/@fortawesome/fontawesome-free/scss/brands.scss";
|
||||
@import "../../node_modules/normalize-scss/sass/normalize/import-now";
|
||||
|
||||
body {
|
||||
background-color: $background_color;
|
||||
|
|
1873
assets/package-lock.json
generated
1873
assets/package-lock.json
generated
File diff suppressed because it is too large
Load diff
|
@ -6,14 +6,15 @@
|
|||
"dependencies": {
|
||||
"brunch": "^2.10.17",
|
||||
"copycat-brunch": "^1.1.1",
|
||||
"font-awesome": "^4.7.0"
|
||||
"@fortawesome/fontawesome-free": "^5.11.2"
|
||||
},
|
||||
"devDependencies": {
|
||||
"acorn": "^7.0.0",
|
||||
"autoprefixer": "^9.5.1",
|
||||
"acorn": "^7.1.0",
|
||||
"autoprefixer": "^9.7.3",
|
||||
"normalize-scss": "^7.0.1",
|
||||
"rollup-brunch": "git+https://github.com/liamwhite/rollup-brunch#31967fc",
|
||||
"sass-brunch": "git+https://github.com/brunch/sass-brunch#e9c0bfe",
|
||||
"rollup-brunch": "git+https://github.com/liamwhite/rollup-brunch.git#31967fc",
|
||||
"sass-brunch": "git+https://github.com/brunch/sass-brunch.git#e9c0bfe",
|
||||
"spostcss-brunch": "git+https://github.com/Meow/spostcss-brunch.git#b64df45",
|
||||
"uglify-js-brunch": "^2.10.0"
|
||||
}
|
||||
}
|
||||
|
|
|
@ -101,4 +101,14 @@ defmodule Philomena.DnpEntries do
|
|||
def change_dnp_entry(%DnpEntry{} = dnp_entry) do
|
||||
DnpEntry.changeset(dnp_entry, %{})
|
||||
end
|
||||
|
||||
def count_dnp_entries(user) do
|
||||
if Canada.Can.can?(user, :manage, DnpEntry) do
|
||||
DnpEntry
|
||||
|> where([dnp], dnp.aasm_state in ["requested", "claimed", "acknowledged"])
|
||||
|> Repo.aggregate(:count, :id)
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -114,4 +114,14 @@ defmodule Philomena.DuplicateReports do
|
|||
def change_duplicate_report(%DuplicateReport{} = duplicate_report) do
|
||||
DuplicateReport.changeset(duplicate_report, %{})
|
||||
end
|
||||
|
||||
def count_duplicate_reports(user) do
|
||||
if Canada.Can.can?(user, :manage, DuplicateReport) do
|
||||
DuplicateReport
|
||||
|> where(state: "open")
|
||||
|> Repo.aggregate(:count, :id)
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -116,4 +116,14 @@ defmodule Philomena.Reports do
|
|||
|
||||
report
|
||||
end
|
||||
|
||||
def count_reports(user) do
|
||||
if Canada.Can.can?(user, :manage, Report) do
|
||||
Report
|
||||
|> where(open: true)
|
||||
|> Repo.aggregate(:count, :id)
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
|
@ -104,4 +104,14 @@ defmodule Philomena.UserLinks do
|
|||
def change_user_link(%UserLink{} = user_link) do
|
||||
UserLink.changeset(user_link, %{})
|
||||
end
|
||||
|
||||
def count_user_links(user) do
|
||||
if Canada.Can.can?(user, :edit, UserLink) do
|
||||
UserLink
|
||||
|> where(aasm_state: "unverified")
|
||||
|> Repo.aggregate(:count, :id)
|
||||
else
|
||||
nil
|
||||
end
|
||||
end
|
||||
end
|
||||
|
|
48
lib/philomena_web/plugs/admin_counters_plug.ex
Normal file
48
lib/philomena_web/plugs/admin_counters_plug.ex
Normal file
|
@ -0,0 +1,48 @@
|
|||
defmodule PhilomenaWeb.AdminCountersPlug do
|
||||
@moduledoc """
|
||||
This plug stores the counts used by the admin bar.
|
||||
## Example
|
||||
plug PhilomenaWeb.AdminCountersPlug
|
||||
"""
|
||||
|
||||
alias Plug.Conn
|
||||
alias Philomena.DuplicateReports
|
||||
alias Philomena.Reports
|
||||
alias Philomena.UserLinks
|
||||
alias Philomena.DnpEntries
|
||||
|
||||
import Plug.Conn, only: [assign: 3]
|
||||
|
||||
@doc false
|
||||
@spec init(any()) :: any()
|
||||
def init(opts), do: opts
|
||||
|
||||
@doc false
|
||||
@spec call(Plug.Conn.t()) :: Plug.Conn.t()
|
||||
def call(conn), do: call(conn, nil)
|
||||
|
||||
@doc false
|
||||
@spec call(Plug.Conn.t(), any()) :: Plug.Conn.t()
|
||||
def call(conn, _opts) do
|
||||
user = conn.assigns.current_user
|
||||
|
||||
maybe_assign_admin_metrics(conn, user, staff?(user))
|
||||
end
|
||||
|
||||
defp maybe_assign_admin_metrics(conn, _user, false), do: conn
|
||||
defp maybe_assign_admin_metrics(conn, user, true) do
|
||||
duplicate_reports = DuplicateReports.count_duplicate_reports(user)
|
||||
reports = Reports.count_reports(user)
|
||||
user_links = UserLinks.count_user_links(user)
|
||||
dnps = DnpEntries.count_dnp_entries(user)
|
||||
|
||||
conn
|
||||
|> assign(:duplicate_report_count, duplicate_reports)
|
||||
|> assign(:report_count, reports)
|
||||
|> assign(:user_link_count, user_links)
|
||||
|> assign(:dnp_entry_count, dnps)
|
||||
end
|
||||
|
||||
defp staff?(%{role: role}) when role in ["assistant", "moderator", "admin"], do: true
|
||||
defp staff?(_user), do: false
|
||||
end
|
|
@ -20,6 +20,7 @@ defmodule PhilomenaWeb.Router do
|
|||
plug PhilomenaWeb.ForumListPlug
|
||||
plug PhilomenaWeb.FilterSelectPlug
|
||||
plug PhilomenaWeb.ChannelPlug
|
||||
plug PhilomenaWeb.AdminCountersPlug
|
||||
end
|
||||
|
||||
pipeline :api do
|
||||
|
|
|
@ -2,14 +2,10 @@ 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, conn: @conn
|
||||
|
||||
.flex__grow.communication__body
|
||||
|
||||
span.communication__body__sender-name = render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @comment, awards: true, conn: @conn
|
||||
br
|
||||
|
||||
= render PhilomenaWeb.UserAttributionView, "_anon_user_title.html", object: @comment, conn: @conn
|
||||
|
||||
.communication__body__text
|
||||
= if @comment.hidden_from_users do
|
||||
strong.comment_deleted
|
||||
|
@ -17,10 +13,20 @@ article.block.communication id="comment_#{@comment.id}"
|
|||
=> @comment.deletion_reason
|
||||
- else
|
||||
==<> @body
|
||||
|
||||
.block__content.communication__options
|
||||
.flex.flex--wrap.flex--spaced-out
|
||||
= render PhilomenaWeb.CommentView, "_comment_options.html", comment: @comment, conn: @conn
|
||||
= if can?(@conn, :hide, @comment) do
|
||||
.js-staff-action
|
||||
/ todo: make delete button work
|
||||
a.communication__interaction.togglable-delete-form-link href="#"
|
||||
i.fa.fa-times
|
||||
=<> "Delete"
|
||||
= if can?(@conn, :manage, @comment) do
|
||||
.communication__info
|
||||
=<> link_to_ip(@comment.ip)
|
||||
.communication__info
|
||||
=<> link_to_fingerprint(@comment.fingerprint)
|
||||
/- if can?(:hide, Comment)
|
||||
/ .js-staff-action
|
||||
/ - if !comment.hidden_from_users && !comment.destroyed_content
|
||||
|
|
|
@ -2,11 +2,11 @@ div
|
|||
p
|
||||
= if can?(@conn, :edit_description, @image) do
|
||||
a.button#edit-description href="#" data-click-focus="#description" data-click-hide=".image-description" data-click-show="#description-form" title="Edit description" accessKey="d"
|
||||
i.fa.fa-pencil>
|
||||
i.fas.fa-edit>
|
||||
' Description:
|
||||
|
||||
- else
|
||||
' Description:
|
||||
|
||||
.image-description__text
|
||||
== @body
|
||||
== @body
|
||||
|
|
|
@ -51,8 +51,14 @@
|
|||
div
|
||||
' Uploaded
|
||||
=> pretty_time(@image.created_at)
|
||||
' by
|
||||
=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @image, awards: true, conn: @conn
|
||||
span.image_uploader
|
||||
' by
|
||||
=> render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @image, awards: true, conn: @conn
|
||||
= if can?(@conn, :manage, @image) do
|
||||
=<> link_to_ip(@image.ip)
|
||||
=<> link_to_fingerprint(@image.fingerprint)
|
||||
a href="#"
|
||||
i.fa.fa-edit
|
||||
span.image-size
|
||||
|
|
||||
= @image.image_width
|
||||
|
|
|
@ -23,7 +23,7 @@
|
|||
.flex.flex--wrap#image-source
|
||||
p
|
||||
a.button.button--separate-right#edit-source data-click-focus="#source-field" data-click-hide="#image-source" data-click-show="#source-form" title="Edit source" accessKey="s"
|
||||
i.fa.fa-pencil>
|
||||
i.fas.fa-edit>
|
||||
' Source:
|
||||
|
||||
p
|
||||
|
@ -37,4 +37,4 @@
|
|||
|
||||
a.button.button--link.button--separate-left href=Routes.image_source_change_path(@conn, :index, @image) title="Source history"
|
||||
i.fa.fa-history>
|
||||
' History
|
||||
' History
|
||||
|
|
|
@ -52,11 +52,11 @@
|
|||
.tagsauce
|
||||
.block
|
||||
a.button.js-tag-sauce-toggle#edit-tags data-click-toggle=".tagsauce, .js-imageform" data-click-focus=".js-taginput-plain:not(.hidden), .js-taginput-input" title="Edit tags" accessKey="t"
|
||||
i.fa.fa-pencil>
|
||||
i.fas.fa-edit>
|
||||
' Tags:
|
||||
|
||||
a.button.button--link.button--separate-left href=Routes.image_tag_change_path(@conn, :index, @image) title="Tag history"
|
||||
i.fa.fa-history>
|
||||
' History
|
||||
|
||||
= render PhilomenaWeb.TagView, "_tag_list.html", tags: display_order(@image.tags), conn: @conn
|
||||
= render PhilomenaWeb.TagView, "_tag_list.html", tags: display_order(@image.tags), conn: @conn
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
.block
|
||||
.block__header.block__header--js-tabbed
|
||||
a.selected href="#" data-click-tab="write"
|
||||
i.fa.fa-pencil>
|
||||
i.fas.fa-edit>
|
||||
' Edit
|
||||
|
||||
a href="#" data-click-tab="preview"
|
||||
|
@ -29,4 +29,4 @@
|
|||
|
||||
= if @conn.assigns.current_user do
|
||||
= checkbox f, :anonymous, value: anonymous_by_default?(@conn)
|
||||
= label f, :anonymous, "Anonymous"
|
||||
= label f, :anonymous, "Anonymous"
|
||||
|
|
|
@ -10,6 +10,7 @@ elixir:
|
|||
=> pluralize("comment", "comments", @image.comments_count)
|
||||
' posted
|
||||
button.button#js-refresh-comments title="Refresh" data-disable-with="..."
|
||||
i.fa.fa-sync
|
||||
span.hide-mobile<> Refresh
|
||||
|
||||
= for {comment, body} <- @comments do
|
||||
|
@ -17,4 +18,4 @@ elixir:
|
|||
|
||||
.block
|
||||
.block__header.block__header--light
|
||||
= pagination
|
||||
= pagination
|
||||
|
|
|
@ -73,7 +73,7 @@ header.header
|
|||
i.fa.fa-fw.fa-comments>
|
||||
| Comments
|
||||
a.header__link href="/posts?pq=my:posts"
|
||||
i.fa.fa-fw.fa-pencil>
|
||||
i.fas.fa-fw.fa-pen-square>
|
||||
| Posts
|
||||
a.header__link href='/user_links'
|
||||
i.fa.fa-fw.fa-link>
|
||||
|
@ -88,7 +88,7 @@ header.header
|
|||
i.fa.fa-fw.fa-user>
|
||||
| Account
|
||||
a.header__link href="/session" data-method='delete'
|
||||
i.fa.fa-fw.fa-sign-out>
|
||||
i.fa.fa-fw.fa-sign-out-alt>
|
||||
| Logout
|
||||
- else
|
||||
a.header__link.hide-mobile href="/filters"
|
||||
|
@ -107,5 +107,5 @@ header.header
|
|||
nav.header.header--secondary
|
||||
.flex.flex--centered.flex--spaced-out.flex--wrap
|
||||
= render PhilomenaWeb.LayoutView, "_header_navigation.html", assigns
|
||||
/- if current_user.try(:staff?)
|
||||
include _header_staff_links.html
|
||||
= if @current_user.role != "user" do
|
||||
= render PhilomenaWeb.LayoutView, "_header_staff_links.html", assigns
|
||||
|
|
|
@ -0,0 +1,85 @@
|
|||
/ Dummy view for the admin bar
|
||||
.flex.flex--centered.header--secondary__admin-links.stretched-mobile-links.js-staff-action
|
||||
.dropdown.hide-mobile
|
||||
/a.header__link title="Admin"
|
||||
' A
|
||||
i.fa.fa-caret-down
|
||||
.dropdown__content.js-burger-links
|
||||
/ todo: make some sort of permission for this
|
||||
= if @current_user.role == "admin" do
|
||||
= link to: "/admin/flipper", class: "header__link" do
|
||||
i.fa.fa-fw.fa-toggle-on>
|
||||
' Site Settings
|
||||
= if can?(@conn, :manage, SiteNotice) do
|
||||
= link to: "/admin/site_notices", class: "header__link" do
|
||||
i.fa.fa-fw.fa-info-circle>
|
||||
' Site Notices
|
||||
= if can?(@conn, :manage, Tag) do
|
||||
= link to: "#", class: "header__link" do
|
||||
i.fa.fa-fw.fa-tags>
|
||||
' Tags
|
||||
= if can?(@conn, :mod_read, User) do
|
||||
= link to: "#", class: "header__link" do
|
||||
i.fa.fa-fw.fa-users>
|
||||
' Users
|
||||
= if can?(@conn, :mod_read, Comment) do
|
||||
= link to: "#", class: "header__link" do
|
||||
i.fa.fa-fw.fa-comments>
|
||||
' Comments
|
||||
= if can?(@conn, :mod_read, Forum) do
|
||||
= link to: "#", class: "header__link" do
|
||||
i.fa.fa-fw.fa-paragraph>
|
||||
' Forums
|
||||
= if can?(@conn, :manage, Advert) do
|
||||
= link to: "#", class: "header__link" do
|
||||
i.fa.fa-fw.fa-shopping-bag>
|
||||
' Advertisements
|
||||
= if can?(@conn, :award, Badge) do
|
||||
= link to: "#", class: "header__link" do
|
||||
i.fa.fa-fw.fa-trophy>
|
||||
' Badges
|
||||
= if can?(@conn, :manage, StaticPage) do
|
||||
= link to: "#", class: "header__link" do
|
||||
i.fa.fa-fw.fa-sticky-note>
|
||||
' Pages
|
||||
= if can?(@conn, :manage, ModNote) do
|
||||
= link to: "#", class: "header__link" do
|
||||
i.fa.fa-fw.fa-sticky-note>
|
||||
' Mod Notes
|
||||
= if @duplicate_report_count do
|
||||
= link to: "#", class: "header__link", title: "Duplicates" do
|
||||
' D
|
||||
span.header__counter__admin
|
||||
= @duplicate_report_count
|
||||
= if @report_count do
|
||||
= link to: "#", class: "header__link", title: "Reports" do
|
||||
' R
|
||||
span.header__counter__admin
|
||||
= @report_count
|
||||
= if @user_link_count do
|
||||
= link to: "#", class: "header__link", title: "User Links" do
|
||||
' L
|
||||
span.header__counter__admin
|
||||
= @user_link_count
|
||||
= if @dnp_entry_count do
|
||||
= link to: "#", class: "header__link", title: "DNP Requests" do
|
||||
' S
|
||||
span.header__counter__admin
|
||||
= @dnp_entry_count
|
||||
.dropdown.hide-mobile
|
||||
a.header__link title="Bans"
|
||||
' B
|
||||
i.fa.fa-caret-down
|
||||
.dropdown__content.dropdown__content-right.js-burger-links
|
||||
= if can?(@conn, :mod_read, UserBan) do
|
||||
= link to: "#", class: "header__link" do
|
||||
i.fa.fa-fw.fa-user>
|
||||
' User Bans
|
||||
= if can?(@conn, :mod_read, SubnetBan) do
|
||||
= link to: "#", class: "header__link" do
|
||||
i.fab.fa-fw.fa-internet-explorer>
|
||||
' IP Bans
|
||||
= if can?(@conn, :mod_read, FingerprintBan) do
|
||||
= link to: "#", class: "header__link" do
|
||||
i.fa.fa-fw.fa-desktop>
|
||||
' FP Bans
|
|
@ -2,13 +2,10 @@ 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, conn: @conn
|
||||
|
||||
.flex__grow.communication__body
|
||||
span.communication__body__sender-name = render PhilomenaWeb.UserAttributionView, "_anon_user.html", object: @post, awards: true, conn: @conn
|
||||
br
|
||||
|
||||
= render PhilomenaWeb.UserAttributionView, "_anon_user_title.html", object: @post, conn: @conn
|
||||
|
||||
.communication__body__text
|
||||
= if @post.hidden_from_users do
|
||||
strong.comment_deleted
|
||||
|
@ -16,12 +13,19 @@ article.block.communication id="post_#{@post.id}"
|
|||
=> @post.deletion_reason
|
||||
- else
|
||||
==<> @body
|
||||
|
||||
|
||||
.block__content.communication__options
|
||||
.flex.flex--wrap.flex--spaced-out
|
||||
= render PhilomenaWeb.PostView, "_post_options.html", conn: @conn, post: @post
|
||||
|
||||
= if can?(@conn, :hide, @post) do
|
||||
/ todo: make post deletion work
|
||||
a.communication__interaction.togglable-delete-form-link href="#"
|
||||
i.fa.fa-times
|
||||
=<> "Delete"
|
||||
= if can?(@conn, :manage, @post) do
|
||||
.communication__info
|
||||
=<> link_to_ip(@post.ip)
|
||||
.communication__info
|
||||
=<> link_to_fingerprint(@post.fingerprint)
|
||||
/- if can?(:hide, Post)
|
||||
/ .js-staff-action
|
||||
/ - if !post.hidden_from_users && !post.destroyed_content
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
.block
|
||||
.block__header.block__header--js-tabbed
|
||||
a.selected href="#" data-click-tab="write"
|
||||
i.fa.fa-pencil>
|
||||
i.fas.fa-pencil-alt>
|
||||
' Create a Topic
|
||||
|
||||
a href="#" data-click-tab="preview"
|
||||
|
@ -83,4 +83,4 @@
|
|||
' [Loading preview...]
|
||||
|
||||
.block__content.communication-edit__actions
|
||||
= submit "Post", class: "button"
|
||||
= submit "Post", class: "button"
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
.block
|
||||
.block__header.block__header--js-tabbed
|
||||
a.selected href="#" data-click-tab="write"
|
||||
i.fa.fa-pencil>
|
||||
i.fas.fa-edit>
|
||||
' Edit
|
||||
|
||||
a href="#" data-click-tab="preview"
|
||||
|
@ -29,4 +29,4 @@
|
|||
|
||||
= if @conn.assigns.current_user do
|
||||
= checkbox f, :anonymous, value: anonymous_by_default?(@conn)
|
||||
= label f, :anonymous, "Anonymous"
|
||||
= label f, :anonymous, "Anonymous"
|
||||
|
|
|
@ -113,4 +113,17 @@ defmodule PhilomenaWeb.AppView do
|
|||
])
|
||||
|> to_string()
|
||||
end
|
||||
|
||||
defp text_or_na(text), do: text
|
||||
defp text_or_na(nil), do: "N/A"
|
||||
|
||||
# todo: make ip a real link
|
||||
def link_to_ip(ip) do
|
||||
link(text_or_na(ip), to: "#")
|
||||
end
|
||||
|
||||
# todo: make fp a real link
|
||||
def link_to_fingerprint(fp) do
|
||||
link(String.slice(text_or_na(fp), 0..6), to: "#")
|
||||
end
|
||||
end
|
||||
|
|
Loading…
Reference in a new issue