@@ -16,10 +16,14 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). | |||
<details> | |||
<summary>API Changes</summary> | |||
- **Breaking:** Pleroma API: The routes to update avatar, banner and background have been removed. | |||
- **Breaking:** Image description length is limited now. | |||
- **Breaking:** Emoji API: changed methods and renamed routes. | |||
- MastodonAPI: Allow removal of avatar, banner and background. | |||
- Streaming: Repeats of a user's posts will no longer be pushed to the user's stream. | |||
- Mastodon API: Added `pleroma.metadata.fields_limits` to /api/v1/instance | |||
- Mastodon API: On deletion, returns the original post text. | |||
- Mastodon API: Add `pleroma.unread_count` to the Marker entity. | |||
</details> | |||
<details> | |||
@@ -58,8 +62,9 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). | |||
- Mastodon API: Extended `/api/v1/instance`. | |||
- Mastodon API: Support for `include_types` in `/api/v1/notifications`. | |||
- Mastodon API: Added `/api/v1/notifications/:id/dismiss` endpoint. | |||
- Mastodon API: Add support for filtering replies in public and home timelines | |||
- Mastodon API: Support for `bot` field in `/api/v1/accounts/update_credentials` | |||
- Mastodon API: Add support for filtering replies in public and home timelines. | |||
- Mastodon API: Support for `bot` field in `/api/v1/accounts/update_credentials`. | |||
- Mastodon API: Support irreversible property for filters. | |||
- Admin API: endpoints for create/update/delete OAuth Apps. | |||
- Admin API: endpoint for status view. | |||
- OTP: Add command to reload emoji packs | |||
@@ -73,6 +78,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). | |||
- Resolving Peertube accounts with Webfinger | |||
- `blob:` urls not being allowed by connect-src CSP | |||
- Mastodon API: fix `GET /api/v1/notifications` not returning the full result set | |||
- Rich Media Previews for Twitter links | |||
## [Unreleased (patch)] | |||
@@ -214,7 +220,6 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/). | |||
- Mastodon API: `pleroma.thread_muted` to the Status entity | |||
- Mastodon API: Mark the direct conversation as read for the author when they send a new direct message | |||
- Mastodon API, streaming: Add `pleroma.direct_conversation_id` to the `conversation` stream event payload. | |||
- Mastodon API: Add `pleroma.unread_count` to the Marker entity | |||
- Admin API: Render whole status in grouped reports | |||
- Mastodon API: User timelines will now respect blocks, unless you are getting the user timeline of somebody you blocked (which would be empty otherwise). | |||
- Mastodon API: Favoriting / Repeating a post multiple times will now return the identical response every time. Before, executing that action twice would return an error ("already favorited") on the second try. | |||
@@ -24,6 +24,7 @@ defmodule Pleroma.LoadTesting.Activities do | |||
@visibility ~w(public private direct unlisted) | |||
@types [ | |||
:simple, | |||
:simple_filtered, | |||
:emoji, | |||
:mentions, | |||
:hell_thread, | |||
@@ -242,6 +243,15 @@ defmodule Pleroma.LoadTesting.Activities do | |||
insert_local_activity(visibility, group, users, "Simple status") | |||
end | |||
defp insert_activity(:simple_filtered, visibility, group, users, _opts) | |||
when group in @remote_groups do | |||
insert_remote_activity(visibility, group, users, "Remote status which must be filtered") | |||
end | |||
defp insert_activity(:simple_filtered, visibility, group, users, _opts) do | |||
insert_local_activity(visibility, group, users, "Simple status which must be filtered") | |||
end | |||
defp insert_activity(:emoji, visibility, group, users, _opts) | |||
when group in @remote_groups do | |||
insert_remote_activity(visibility, group, users, "Remote status with emoji :firefox:") | |||
@@ -32,10 +32,22 @@ defmodule Pleroma.LoadTesting.Fetcher do | |||
) | |||
end | |||
defp create_filter(user) do | |||
Pleroma.Filter.create(%Pleroma.Filter{ | |||
user_id: user.id, | |||
phrase: "must be filtered", | |||
hide: true | |||
}) | |||
end | |||
defp delete_filter(filter), do: Repo.delete(filter) | |||
defp fetch_timelines(user) do | |||
fetch_home_timeline(user) | |||
fetch_home_timeline_with_filter(user) | |||
fetch_direct_timeline(user) | |||
fetch_public_timeline(user) | |||
fetch_public_timeline_with_filter(user) | |||
fetch_public_timeline(user, :with_blocks) | |||
fetch_public_timeline(user, :local) | |||
fetch_public_timeline(user, :tag) | |||
@@ -61,7 +73,7 @@ defmodule Pleroma.LoadTesting.Fetcher do | |||
} | |||
end | |||
defp fetch_home_timeline(user) do | |||
defp fetch_home_timeline(user, title_end \\ "") do | |||
opts = opts_for_home_timeline(user) | |||
recipients = [user.ap_id | User.following(user)] | |||
@@ -84,9 +96,11 @@ defmodule Pleroma.LoadTesting.Fetcher do | |||
|> Enum.reverse() | |||
|> List.last() | |||
title = "home timeline " <> title_end | |||
Benchee.run( | |||
%{ | |||
"home timeline" => fn opts -> ActivityPub.fetch_activities(recipients, opts) end | |||
title => fn opts -> ActivityPub.fetch_activities(recipients, opts) end | |||
}, | |||
inputs: %{ | |||
"1 page" => opts, | |||
@@ -108,6 +122,14 @@ defmodule Pleroma.LoadTesting.Fetcher do | |||
) | |||
end | |||
defp fetch_home_timeline_with_filter(user) do | |||
{:ok, filter} = create_filter(user) | |||
fetch_home_timeline(user, "with filters") | |||
delete_filter(filter) | |||
end | |||
defp opts_for_direct_timeline(user) do | |||
%{ | |||
visibility: "direct", | |||
@@ -210,6 +232,14 @@ defmodule Pleroma.LoadTesting.Fetcher do | |||
fetch_public_timeline(opts, "public timeline") | |||
end | |||
defp fetch_public_timeline_with_filter(user) do | |||
{:ok, filter} = create_filter(user) | |||
opts = opts_for_public_timeline(user) | |||
fetch_public_timeline(opts, "public timeline with filters") | |||
delete_filter(filter) | |||
end | |||
defp fetch_public_timeline(user, :local) do | |||
opts = opts_for_public_timeline(user, :local) | |||
@@ -97,6 +97,7 @@ config :pleroma, :uri_schemes, | |||
"dat", | |||
"dweb", | |||
"gopher", | |||
"hyper", | |||
"ipfs", | |||
"ipns", | |||
"irc", | |||
@@ -188,6 +189,7 @@ config :pleroma, :instance, | |||
background_image: "/images/city.jpg", | |||
instance_thumbnail: "/instance/thumbnail.jpeg", | |||
limit: 5_000, | |||
description_limit: 5_000, | |||
chat_limit: 5_000, | |||
remote_limit: 100_000, | |||
upload_limit: 16_000_000, | |||
@@ -436,8 +438,7 @@ config :pleroma, Pleroma.Web.Metadata, | |||
config :pleroma, Pleroma.Web.Preload, | |||
providers: [ | |||
Pleroma.Web.Preload.Providers.Instance, | |||
Pleroma.Web.Preload.Providers.StatusNet | |||
Pleroma.Web.Preload.Providers.Instance | |||
] | |||
config :pleroma, :http_security, | |||
@@ -498,6 +498,7 @@ config :pleroma, :config_description, [ | |||
"dat", | |||
"dweb", | |||
"gopher", | |||
"hyper", | |||
"ipfs", | |||
"ipns", | |||
"irc", | |||
@@ -699,8 +700,9 @@ config :pleroma, :config_description, [ | |||
key: :public, | |||
type: :boolean, | |||
description: | |||
"Makes the client API in authentificated mode-only except for user-profiles." <> | |||
" Useful for disabling the Local Timeline and The Whole Known Network." | |||
"Makes the client API in authenticated mode-only except for user-profiles." <> | |||
" Useful for disabling the Local Timeline and The Whole Known Network. " <> | |||
" Note: when setting to `false`, please also check `:restrict_unauthenticated` setting." | |||
}, | |||
%{ | |||
key: :quarantined_instances, | |||
@@ -182,10 +182,12 @@ Additional parameters can be added to the JSON body/Form data: | |||
- `pleroma_settings_store` - Opaque user settings to be saved on the backend. | |||
- `skip_thread_containment` - if true, skip filtering out broken threads | |||
- `allow_following_move` - if true, allows automatically follow moved following accounts | |||
- `pleroma_background_image` - sets the background image of the user. | |||
- `pleroma_background_image` - sets the background image of the user. Can be set to "" (an empty string) to reset. | |||
- `discoverable` - if true, discovery of this account in search results and other services is allowed. | |||
- `actor_type` - the type of this account. | |||
All images (avatar, banner and background) can be reset to the default by sending an empty string ("") instead of a file. | |||
### Pleroma Settings Store | |||
Pleroma has mechanism that allows frontends to save blobs of json for each user on the backend. This can be used to save frontend-specific settings for a user that the backend does not need to know about. | |||
@@ -220,6 +222,8 @@ Has theses additional parameters (which are the same as in Pleroma-API): | |||
`GET /api/v1/instance` has additional fields | |||
- `max_toot_chars`: The maximum characters per post | |||
- `chat_limit`: The maximum characters per chat message | |||
- `description_limit`: The maximum characters per image description | |||
- `poll_limits`: The limits of polls | |||
- `upload_limit`: The maximum upload file size | |||
- `avatar_upload_limit`: The same for avatars | |||
@@ -18,6 +18,7 @@ To add configuration to your config file, you can copy it from the base config. | |||
* `notify_email`: Email used for notifications. | |||
* `description`: The instance’s description, can be seen in nodeinfo and ``/api/v1/instance``. | |||
* `limit`: Posts character limit (CW/Subject included in the counter). | |||
* `discription_limit`: The character limit for image descriptions. | |||
* `chat_limit`: Character limit of the instance chat messages. | |||
* `remote_limit`: Hard character limit beyond which remote posts will be dropped. | |||
* `upload_limit`: File size limit of uploads (except for avatar, background, banner). | |||
@@ -36,7 +37,7 @@ To add configuration to your config file, you can copy it from the base config. | |||
* `federation_incoming_replies_max_depth`: Max. depth of reply-to activities fetching on incoming federation, to prevent out-of-memory situations while fetching very long threads. If set to `nil`, threads of any depth will be fetched. Lower this value if you experience out-of-memory crashes. | |||
* `federation_reachability_timeout_days`: Timeout (in days) of each external federation target being unreachable prior to pausing federating to it. | |||
* `allow_relay`: Enable Pleroma’s Relay, which makes it possible to follow a whole instance. | |||
* `public`: Makes the client API in authenticated mode-only except for user-profiles. Useful for disabling the Local Timeline and The Whole Known Network. | |||
* `public`: Makes the client API in authenticated mode-only except for user-profiles. Useful for disabling the Local Timeline and The Whole Known Network. See also: `restrict_unauthenticated`. | |||
* `quarantined_instances`: List of ActivityPub instances where private(DMs, followers-only) activities will not be send. | |||
* `managed_config`: Whenether the config for pleroma-fe is configured in [:frontend_configurations](#frontend_configurations) or in ``static/config.json``. | |||
* `allowed_post_formats`: MIME-type list of formats allowed to be posted (transformed into HTML). | |||
@@ -970,11 +971,11 @@ config :pleroma, :database_config_whitelist, [ | |||
### :restrict_unauthenticated | |||
Restrict access for unauthenticated users to timelines (public and federate), user profiles and statuses. | |||
Restrict access for unauthenticated users to timelines (public and federated), user profiles and statuses. | |||
* `timelines`: public and federated timelines | |||
* `local`: public timeline | |||
* `federated` | |||
* `federated`: federated timeline (includes public timeline) | |||
* `profiles`: user profiles | |||
* `local` | |||
* `remote` | |||
@@ -982,6 +983,7 @@ Restrict access for unauthenticated users to timelines (public and federate), us | |||
* `local` | |||
* `remote` | |||
Note: setting `restrict_unauthenticated/timelines/local` to `true` has no practical sense if `restrict_unauthenticated/timelines/federated` is set to `false` (since local public activities will still be delivered to unauthenticated users as part of federated timeline). | |||
## Pleroma.Web.ApiSpec.CastAndValidate | |||
@@ -34,10 +34,18 @@ defmodule Pleroma.Filter do | |||
Repo.one(query) | |||
end | |||
def get_filters(%User{id: user_id} = _user) do | |||
def get_active(query) do | |||
from(f in query, where: is_nil(f.expires_at) or f.expires_at > ^NaiveDateTime.utc_now()) | |||
end | |||
def get_irreversible(query) do | |||
from(f in query, where: f.hide) | |||
end | |||
def get_filters(query \\ __MODULE__, %User{id: user_id}) do | |||
query = | |||
from( | |||
f in Pleroma.Filter, | |||
f in query, | |||
where: f.user_id == ^user_id, | |||
order_by: [desc: :id] | |||
) | |||
@@ -95,4 +103,34 @@ defmodule Pleroma.Filter do | |||
|> validate_required([:phrase, :context]) | |||
|> Repo.update() | |||
end | |||
def compose_regex(user_or_filters, format \\ :postgres) | |||
def compose_regex(%User{} = user, format) do | |||
__MODULE__ | |||
|> get_active() | |||
|> get_irreversible() | |||
|> get_filters(user) | |||
|> compose_regex(format) | |||
end | |||
def compose_regex([_ | _] = filters, format) do | |||
phrases = | |||
filters | |||
|> Enum.map(& &1.phrase) | |||
|> Enum.join("|") | |||
case format do | |||
:postgres -> | |||
"\\y(#{phrases})\\y" | |||
:re -> | |||
~r/\b#{phrases}\b/i | |||
_ -> | |||
nil | |||
end | |||
end | |||
def compose_regex(_, _), do: nil | |||
end |
@@ -130,6 +130,7 @@ defmodule Pleroma.Notification do | |||
|> preload([n, a, o], activity: {a, object: o}) | |||
|> exclude_notification_muted(user, exclude_notification_muted_opts) | |||
|> exclude_blocked(user, exclude_blocked_opts) | |||
|> exclude_filtered(user) | |||
|> exclude_visibility(opts) | |||
end | |||
@@ -158,6 +159,20 @@ defmodule Pleroma.Notification do | |||
|> where([n, a, o, tm], is_nil(tm.user_id)) | |||
end | |||
defp exclude_filtered(query, user) do | |||
case Pleroma.Filter.compose_regex(user) do | |||
nil -> | |||
query | |||
regex -> | |||
from([_n, a, o] in query, | |||
where: | |||
fragment("not(?->>'content' ~* ?)", o.data, ^regex) or | |||
fragment("?->>'actor' = ?", o.data, ^user.ap_id) | |||
) | |||
end | |||
end | |||
@valid_visibilities ~w[direct unlisted public private] | |||
defp exclude_visibility(query, %{exclude_visibilities: visibility}) | |||
@@ -337,6 +352,7 @@ defmodule Pleroma.Notification do | |||
end | |||
end | |||
@spec create_notifications(Activity.t(), keyword()) :: {:ok, [Notification.t()] | []} | |||
def create_notifications(activity, options \\ []) | |||
def create_notifications(%Activity{data: %{"to" => _, "type" => "Create"}} = activity, options) do | |||
@@ -555,7 +571,8 @@ defmodule Pleroma.Notification do | |||
:follows, | |||
:non_followers, | |||
:non_follows, | |||
:recently_followed | |||
:recently_followed, | |||
:filtered | |||
] | |||
|> Enum.find(&skip?(&1, activity, user)) | |||
end | |||
@@ -624,6 +641,26 @@ defmodule Pleroma.Notification do | |||
end) | |||
end | |||
def skip?(:filtered, %{data: %{"type" => type}}, _) when type in ["Follow", "Move"], do: false | |||
def skip?(:filtered, activity, user) do | |||
object = Object.normalize(activity) | |||
cond do | |||
is_nil(object) -> | |||
false | |||
object.data["actor"] == user.ap_id -> | |||
false | |||
not is_nil(regex = Pleroma.Filter.compose_regex(user, :re)) -> | |||
Regex.match?(regex, object.data["content"]) | |||
true -> | |||
false | |||
end | |||
end | |||
def skip?(_, _, _), do: false | |||
def for_user_and_activity(user, activity) do | |||
@@ -9,7 +9,7 @@ defmodule Pleroma.Plugs.StaticFEPlug do | |||
def init(options), do: options | |||
def call(conn, _) do | |||
if enabled?() and accepts_html?(conn) do | |||
if enabled?() and requires_html?(conn) do | |||
conn | |||
|> StaticFEController.call(:show) | |||
|> halt() | |||
@@ -20,10 +20,7 @@ defmodule Pleroma.Plugs.StaticFEPlug do | |||
defp enabled?, do: Pleroma.Config.get([:static_fe, :enabled], false) | |||
defp accepts_html?(conn) do | |||
case get_req_header(conn, "accept") do | |||
[accept | _] -> String.contains?(accept, "text/html") | |||
_ -> false | |||
end | |||
defp requires_html?(conn) do | |||
Phoenix.Controller.get_format(conn) == "html" | |||
end | |||
end |
@@ -63,6 +63,10 @@ defmodule Pleroma.Upload do | |||
with {:ok, upload} <- prepare_upload(upload, opts), | |||
upload = %__MODULE__{upload | path: upload.path || "#{upload.id}/#{upload.name}"}, | |||
{:ok, upload} <- Pleroma.Upload.Filter.filter(opts.filters, upload), | |||
description = Map.get(opts, :description) || upload.name, | |||
{_, true} <- | |||
{:description_limit, | |||
String.length(description) <= Pleroma.Config.get([:instance, :description_limit])}, | |||
{:ok, url_spec} <- Pleroma.Uploaders.Uploader.put_file(opts.uploader, upload) do | |||
{:ok, | |||
%{ | |||
@@ -75,9 +79,12 @@ defmodule Pleroma.Upload do | |||
"href" => url_from_spec(upload, opts.base_url, url_spec) | |||
} | |||
], | |||
"name" => Map.get(opts, :description) || upload.name | |||
"name" => description | |||
}} | |||
else | |||
{:description_limit, _} -> | |||
{:error, :description_too_long} | |||
{:error, error} -> | |||
Logger.error( | |||
"#{__MODULE__} store (using #{inspect(opts.uploader)}) failed: #{inspect(error)}" | |||
@@ -89,7 +89,7 @@ defmodule Pleroma.User do | |||
field(:keys, :string) | |||
field(:public_key, :string) | |||
field(:ap_id, :string) | |||
field(:avatar, :map) | |||
field(:avatar, :map, default: %{}) | |||
field(:local, :boolean, default: true) | |||
field(:follower_address, :string) | |||
field(:following_address, :string) | |||
@@ -539,14 +539,11 @@ defmodule Pleroma.User do | |||
end | |||
defp put_change_if_present(changeset, map_field, value_function) do | |||
if value = get_change(changeset, map_field) do | |||
with {:ok, new_value} <- value_function.(value) do | |||
put_change(changeset, map_field, new_value) | |||
else | |||
_ -> changeset | |||
end | |||
with {:ok, value} <- fetch_change(changeset, map_field), | |||
{:ok, new_value} <- value_function.(value) do | |||
put_change(changeset, map_field, new_value) | |||
else | |||
changeset | |||
_ -> changeset | |||
end | |||
end | |||
@@ -10,6 +10,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do | |||
alias Pleroma.Constants | |||
alias Pleroma.Conversation | |||
alias Pleroma.Conversation.Participation | |||
alias Pleroma.Filter | |||
alias Pleroma.Maps | |||
alias Pleroma.Notification | |||
alias Pleroma.Object | |||
@@ -446,6 +447,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do | |||
|> maybe_set_thread_muted_field(opts) | |||
|> restrict_blocked(opts) | |||
|> restrict_recipients(recipients, opts[:user]) | |||
|> restrict_filtered(opts) | |||
|> where( | |||
[activity], | |||
fragment( | |||
@@ -961,6 +963,26 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do | |||
defp restrict_instance(query, _), do: query | |||
defp restrict_filtered(query, %{user: %User{} = user}) do | |||
case Filter.compose_regex(user) do | |||
nil -> | |||
query | |||
regex -> | |||
from([activity, object] in query, | |||
where: | |||
fragment("not(?->>'content' ~* ?)", object.data, ^regex) or | |||
activity.actor == ^user.ap_id | |||
) | |||
end | |||
end | |||
defp restrict_filtered(query, %{blocking_user: %User{} = user}) do | |||
restrict_filtered(query, %{user: user}) | |||
end | |||
defp restrict_filtered(query, _), do: query | |||
defp exclude_poll_votes(query, %{include_poll_votes: true}), do: query | |||
defp exclude_poll_votes(query, _) do | |||
@@ -1091,6 +1113,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do | |||
|> restrict_favorited_by(opts) | |||
|> restrict_blocked(restrict_blocked_opts) | |||
|> restrict_muted(restrict_muted_opts) | |||
|> restrict_filtered(opts) | |||
|> restrict_media(opts) | |||
|> restrict_visibility(opts) | |||
|> restrict_thread_visibility(opts, config) | |||
@@ -1099,6 +1122,7 @@ defmodule Pleroma.Web.ActivityPub.ActivityPub do | |||
|> restrict_muted_reblogs(restrict_muted_reblogs_opts) | |||
|> restrict_instance(opts) | |||
|> restrict_announce_object_actor(opts) | |||
|> restrict_filtered(opts) | |||
|> Activity.restrict_deactivated_users() | |||
|> exclude_poll_votes(opts) | |||
|> exclude_chat_messages(opts) | |||
@@ -233,18 +233,24 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do | |||
is_map(url) && is_binary(url["href"]) -> url["href"] | |||
is_binary(data["url"]) -> data["url"] | |||
is_binary(data["href"]) -> data["href"] | |||
true -> nil | |||
end | |||
attachment_url = | |||
%{"href" => href} | |||
|> Maps.put_if_present("mediaType", media_type) | |||
|> Maps.put_if_present("type", Map.get(url || %{}, "type")) | |||
if href do | |||
attachment_url = | |||
%{"href" => href} | |||
|> Maps.put_if_present("mediaType", media_type) | |||
|> Maps.put_if_present("type", Map.get(url || %{}, "type")) | |||
%{"url" => [attachment_url]} | |||
|> Maps.put_if_present("mediaType", media_type) | |||
|> Maps.put_if_present("type", data["type"]) | |||
|> Maps.put_if_present("name", data["name"]) | |||
%{"url" => [attachment_url]} | |||
|> Maps.put_if_present("mediaType", media_type) | |||
|> Maps.put_if_present("type", data["type"]) | |||
|> Maps.put_if_present("name", data["name"]) | |||
else | |||
nil | |||
end | |||
end) | |||
|> Enum.filter(& &1) | |||
Map.put(object, "attachment", attachments) | |||
end | |||
@@ -263,12 +269,18 @@ defmodule Pleroma.Web.ActivityPub.Transmogrifier do | |||
def fix_url(%{"type" => object_type, "url" => url} = object) | |||
when object_type in ["Video", "Audio"] and is_list(url) do | |||
first_element = Enum.at(url, 0) | |||
attachment = | |||
Enum.find(url, fn x -> | |||
media_type = x["mediaType"] || x["mimeType"] || "" | |||
is_map(x) and String.starts_with?(media_type, ["audio/", "video/"]) | |||
end) | |||
link_element = Enum.find(url, fn x -> is_map(x) and x["mimeType"] == "text/html" end) | |||
link_element = | |||
Enum.find(url, fn x -> is_map(x) and (x["mediaType"] || x["mimeType"]) == "text/html" end) | |||
object | |||
|> Map.put("attachment", [first_element]) | |||
|> Map.put("attachment", [attachment]) | |||
|> Map.put("url", link_element["href"]) | |||
end | |||
@@ -4,7 +4,6 @@ | |||
defmodule Pleroma.Web.ApiSpec.PleromaAccountOperation do | |||
alias OpenApiSpex.Operation | |||
alias OpenApiSpex.Schema | |||
alias Pleroma.Web.ApiSpec.Schemas.AccountRelationship | |||
alias Pleroma.Web.ApiSpec.Schemas.ApiError | |||
alias Pleroma.Web.ApiSpec.Schemas.FlakeID | |||
@@ -40,48 +39,6 @@ defmodule Pleroma.Web.ApiSpec.PleromaAccountOperation do | |||
} | |||
end | |||
def update_avatar_operation do | |||
%Operation{ | |||
tags: ["Accounts"], | |||
summary: "Set/clear user avatar image", | |||
operationId: "PleromaAPI.AccountController.update_avatar", | |||
requestBody: | |||
request_body("Parameters", update_avatar_or_background_request(), required: true), | |||
security: [%{"oAuth" => ["write:accounts"]}], | |||
responses: %{ | |||
200 => update_response(), | |||
403 => Operation.response("Forbidden", "application/json", ApiError) | |||
} | |||
} | |||
end | |||
def update_banner_operation do | |||
%Operation{ | |||
tags: ["Accounts"], | |||
summary: "Set/clear user banner image", | |||
operationId: "PleromaAPI.AccountController.update_banner", | |||
requestBody: request_body("Parameters", update_banner_request(), required: true), | |||
security: [%{"oAuth" => ["write:accounts"]}], | |||
responses: %{ | |||
200 => update_response() | |||
} | |||
} | |||
end | |||
def update_background_operation do | |||
%Operation{ | |||
tags: ["Accounts"], | |||
summary: "Set/clear user background image", | |||
operationId: "PleromaAPI.AccountController.update_background", | |||
security: [%{"oAuth" => ["write:accounts"]}], | |||
requestBody: | |||
request_body("Parameters", update_avatar_or_background_request(), required: true), | |||
responses: %{ | |||
200 => update_response() | |||
} | |||
} | |||
end | |||
def favourites_operation do | |||
%Operation{ | |||
tags: ["Accounts"], | |||
@@ -136,52 +93,4 @@ defmodule Pleroma.Web.ApiSpec.PleromaAccountOperation do | |||
required: true | |||
) | |||
end | |||
defp update_avatar_or_background_request do | |||
%Schema{ | |||
title: "PleromaAccountUpdateAvatarOrBackgroundRequest", | |||
type: :object, | |||
properties: %{ | |||
img: %Schema{ | |||
nullable: true, | |||
type: :string, | |||
format: :binary, | |||
description: "Image encoded using `multipart/form-data` or an empty string to clear" | |||
} | |||
} | |||
} | |||
end | |||
defp update_banner_request do | |||
%Schema{ | |||
title: "PleromaAccountUpdateBannerRequest", | |||
type: :object, | |||
properties: %{ | |||
banner: %Schema{ | |||
type: :string, | |||
nullable: true, | |||
format: :binary, | |||
description: "Image encoded using `multipart/form-data` or an empty string to clear" | |||
} | |||
} | |||
} | |||
end | |||
defp update_response do | |||
Operation.response("PleromaAccountUpdateResponse", "application/json", %Schema{ | |||
type: :object, | |||
properties: %{ | |||
url: %Schema{ | |||
type: :string, | |||
format: :uri, | |||
nullable: true, | |||
description: "Image URL" | |||
} | |||
}, | |||
example: %{ | |||
"url" => | |||
"https://cofe.party/media/9d0add56-bcb6-4c0f-8225-cbbd0b6dd773/13eadb6972c9ccd3f4ffa3b8196f0e0d38b4d2f27594457c52e52946c054cd9a.gif" | |||
} | |||
}) | |||
end | |||
end |
@@ -148,6 +148,13 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do | |||
|> Enum.filter(fn {_, value} -> not is_nil(value) end) | |||
|> Enum.into(%{}) | |||
# We use an empty string as a special value to reset | |||
# avatars, banners, backgrounds | |||
user_image_value = fn | |||
"" -> {:ok, nil} | |||
value -> {:ok, value} | |||
end | |||
user_params = | |||
[ | |||
:no_rich_text, | |||
@@ -168,9 +175,9 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do | |||
|> Maps.put_if_present(:name, params[:display_name]) | |||
|> Maps.put_if_present(:bio, params[:note]) | |||
|> Maps.put_if_present(:raw_bio, params[:note]) | |||
|> Maps.put_if_present(:avatar, params[:avatar]) | |||
|> Maps.put_if_present(:banner, params[:header]) | |||
|> Maps.put_if_present(:background, params[:pleroma_background_image]) | |||
|> Maps.put_if_present(:avatar, params[:avatar], user_image_value) | |||
|> Maps.put_if_present(:banner, params[:header], user_image_value) | |||
|> Maps.put_if_present(:background, params[:pleroma_background_image], user_image_value) | |||
|> Maps.put_if_present( | |||
:raw_fields, | |||
params[:fields_attributes], | |||
@@ -88,21 +88,20 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do | |||
) | |||
end | |||
defp restrict_unauthenticated?(true = _local_only) do | |||
Pleroma.Config.get([:restrict_unauthenticated, :timelines, :local]) | |||
end | |||
defp restrict_unauthenticated?(_) do | |||
Pleroma.Config.get([:restrict_unauthenticated, :timelines, :federated]) | |||
end | |||
# GET /api/v1/timelines/public | |||
def public(%{assigns: %{user: user}} = conn, params) do | |||
local_only = params[:local] | |||
cfg_key = | |||
if local_only do | |||
:local | |||
else | |||
:federated | |||
end | |||
restrict? = Pleroma.Config.get([:restrict_unauthenticated, :timelines, cfg_key]) | |||
if restrict? and is_nil(user) do | |||
render_error(conn, :unauthorized, "authorization required for timeline view") | |||
if is_nil(user) and restrict_unauthenticated?(local_only) do | |||
fail_on_bad_auth(conn) | |||
else | |||
activities = | |||
params | |||
@@ -123,6 +122,10 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do | |||
end | |||
end | |||
defp fail_on_bad_auth(conn) do | |||
render_error(conn, :unauthorized, "authorization required for timeline view") | |||
end | |||
defp hashtag_fetching(params, user, local_only) do | |||
tags = | |||
[params[:tag], params[:any]] | |||
@@ -157,15 +160,20 @@ defmodule Pleroma.Web.MastodonAPI.TimelineController do | |||
# GET /api/v1/timelines/tag/:tag | |||
def hashtag(%{assigns: %{user: user}} = conn, params) do | |||
local_only = params[:local] | |||
activities = hashtag_fetching(params, user, local_only) | |||
conn | |||
|> add_link_headers(activities, %{"local" => local_only}) | |||
|> render("index.json", | |||
activities: activities, | |||
for: user, | |||
as: :activity | |||
) | |||
if is_nil(user) and restrict_unauthenticated?(local_only) do | |||
fail_on_bad_auth(conn) | |||
else | |||
activities = hashtag_fetching(params, user, local_only) | |||
conn | |||
|> add_link_headers(activities, %{"local" => local_only}) | |||
|> render("index.json", | |||
activities: activities, | |||
for: user, | |||
as: :activity | |||
) | |||
end | |||
end | |||
# GET /api/v1/timelines/list/:list_id | |||
@@ -34,6 +34,8 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do | |||
background_upload_limit: Keyword.get(instance, :background_upload_limit), | |||
banner_upload_limit: Keyword.get(instance, :banner_upload_limit), | |||
background_image: Keyword.get(instance, :background_image), | |||
chat_limit: Keyword.get(instance, :chat_limit), | |||
description_limit: Keyword.get(instance, :description_limit), | |||
pleroma: %{ | |||
metadata: %{ | |||
account_activation_required: Keyword.get(instance, :account_activation_required), | |||
@@ -8,7 +8,6 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do | |||
import Pleroma.Web.ControllerHelper, | |||
only: [json_response: 3, add_link_headers: 2, assign_account_by_id: 2] | |||
alias Ecto.Changeset | |||
alias Pleroma.Plugs.EnsurePublicOrAuthenticatedPlug | |||
alias Pleroma.Plugs.OAuthScopesPlug | |||
alias Pleroma.Plugs.RateLimiter | |||
@@ -37,17 +36,6 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do | |||
plug( | |||
OAuthScopesPlug, | |||
%{scopes: ["write:accounts"]} | |||
# Note: the following actions are not permission-secured in Mastodon: | |||
when action in [ | |||
:update_avatar, | |||
:update_banner, | |||
:update_background | |||
] | |||
) | |||
plug( | |||
OAuthScopesPlug, | |||
%{scopes: ["read:favourites"], fallback: :proceed_unauthenticated} when action == :favourites | |||
) | |||
@@ -68,56 +56,6 @@ defmodule Pleroma.Web.PleromaAPI.AccountController do | |||
end | |||
end | |||
@doc "PATCH /api/v1/pleroma/accounts/update_avatar" | |||
def update_avatar(%{assigns: %{user: user}, body_params: %{img: ""}} = conn, _) do | |||
{:ok, _user} = | |||
user | |||
|> Changeset.change(%{avatar: nil}) | |||
|> User.update_and_set_cache() | |||
json(conn, %{url: nil}) | |||
end | |||
def update_avatar(%{assigns: %{user: user}, body_params: params} = conn, _params) do | |||
{:ok, %{data: data}} = ActivityPub.upload(params, type: :avatar) | |||
{:ok, _user} = user |> Changeset.change(%{avatar: data}) |> User.update_and_set_cache() | |||
%{"url" => [%{"href" => href} | _]} = data | |||
json(conn, %{url: href}) | |||
end | |||
@doc "PATCH /api/v1/pleroma/accounts/update_banner" | |||
def update_banner(%{assigns: %{user: user}, body_params: %{banner: ""}} = conn, _) do | |||
with {:ok, _user} <- User.update_banner(user, %{}) do | |||
json(conn, %{url: nil}) | |||
end | |||
end | |||
def update_banner(%{assigns: %{user: user}, body_params: params} = conn, _) do | |||
with {:ok, object} <- ActivityPub.upload(%{img: params[:banner]}, type: :banner), | |||
{:ok, _user} <- User.update_banner(user, object.data) do | |||
%{"url" => [%{"href" => href} | _]} = object.data | |||
json(conn, %{url: href}) | |||
end | |||
end | |||
@doc "PATCH /api/v1/pleroma/accounts/update_background" | |||
def update_background(%{assigns: %{user: user}, body_params: %{img: ""}} = conn, _) do | |||
with {:ok, _user} <- User.update_background(user, %{}) do | |||
json(conn, %{url: nil}) | |||
end | |||
end | |||
def update_background(%{assigns: %{user: user}, body_params: params} = conn, _) do | |||
with {:ok, object} <- ActivityPub.upload(params, type: :background), | |||
{:ok, _user} <- User.update_background(user, object.data) do | |||
%{"url" => [%{"href" => href} | _]} = object.data | |||
json(conn, %{url: href}) | |||
end | |||
end | |||
@doc "GET /api/v1/pleroma/accounts/:id/favourites" | |||
def favourites(%{assigns: %{account: %{hide_favorites: true}}} = conn, _params) do | |||
render_error(conn, :forbidden, "Can't get favorites") | |||
@@ -1,25 +0,0 @@ | |||
# Pleroma: A lightweight social networking server | |||
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/> | |||
# SPDX-License-Identifier: AGPL-3.0-only | |||
defmodule Pleroma.Web.Preload.Providers.StatusNet do | |||
alias Pleroma.Web.Preload.Providers.Provider | |||
alias Pleroma.Web.TwitterAPI.UtilController | |||
@behaviour Provider | |||
@config_url "/api/statusnet/config.json" | |||
@impl Provider | |||
def generate_terms(_params) do | |||
%{} | |||
|> build_config_tag() | |||
end | |||
defp build_config_tag(acc) do | |||
resp = | |||
Plug.Test.conn(:get, @config_url |> to_string()) | |||
|> UtilController.config(nil) | |||
Map.put(acc, @config_url, resp.resp_body) | |||
end | |||
end |
@@ -86,7 +86,10 @@ defmodule Pleroma.Web.RichMedia.Parser do | |||
end | |||
try do | |||
{:ok, %Tesla.Env{body: html}} = Pleroma.HTTP.get(url, [], adapter: opts) | |||
rich_media_agent = Pleroma.Application.user_agent() <> "; Bot" | |||
{:ok, %Tesla.Env{body: html}} = | |||
Pleroma.HTTP.get(url, [{"user-agent", rich_media_agent}], adapter: opts) | |||
html | |||
|> parse_html() | |||
@@ -328,10 +328,6 @@ defmodule Pleroma.Web.Router do | |||
delete("/statuses/:id/reactions/:emoji", EmojiReactionController, :delete) | |||
post("/notifications/read", NotificationController, :mark_as_read) | |||
patch("/accounts/update_avatar", AccountController, :update_avatar) | |||
patch("/accounts/update_banner", AccountController, :update_banner) | |||
patch("/accounts/update_background", AccountController, :update_background) | |||
get("/mascot", MascotController, :show) | |||
put("/mascot", MascotController, :update) | |||
@@ -516,10 +512,6 @@ defmodule Pleroma.Web.Router do | |||
scope "/api", Pleroma.Web do | |||
pipe_through(:config) | |||
get("/help/test", TwitterAPI.UtilController, :help_test) | |||
post("/help/test", TwitterAPI.UtilController, :help_test) | |||
get("/statusnet/config", TwitterAPI.UtilController, :config) | |||
get("/statusnet/version", TwitterAPI.UtilController, :version) | |||
get("/pleroma/frontend_configurations", TwitterAPI.UtilController, :frontend_configurations) | |||
end | |||
@@ -13,9 +13,7 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do | |||
alias Pleroma.Notification | |||
alias Pleroma.Plugs.OAuthScopesPlug | |||
alias Pleroma.User | |||
alias Pleroma.Web | |||
alias Pleroma.Web.CommonAPI | |||
alias Pleroma.Web.TwitterAPI.UtilView | |||
alias Pleroma.Web.WebFinger | |||
plug(Pleroma.Web.FederatingPlug when action == :remote_subscribe) | |||
@@ -42,12 +40,6 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do | |||
plug(OAuthScopesPlug, %{scopes: ["write:notifications"]} when action == :notifications_read) | |||
plug(Pleroma.Plugs.SetFormatPlug when action in [:config, :version]) | |||
def help_test(conn, _params) do | |||
json(conn, "ok") | |||
end | |||
def remote_subscribe(conn, %{"nickname" => nick, "profile" => _}) do | |||
with %User{} = user <- User.get_cached_by_nickname(nick), | |||
avatar = User.avatar_url(user) do | |||
@@ -89,60 +81,6 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do | |||
end | |||
end | |||
def config(%{assigns: %{format: "xml"}} = conn, _params) do | |||
instance = Pleroma.Config.get(:instance) | |||
response = UtilView.status_net_config(instance) | |||
conn | |||
|> put_resp_content_type("application/xml") | |||
|> send_resp(200, response) | |||
end | |||
def config(conn, _params) do | |||
instance = Pleroma.Config.get(:instance) | |||
vapid_public_key = Keyword.get(Pleroma.Web.Push.vapid_config(), :public_key) | |||
uploadlimit = %{ | |||
uploadlimit: to_string(Keyword.get(instance, :upload_limit)), | |||
avatarlimit: to_string(Keyword.get(instance, :avatar_upload_limit)), | |||
backgroundlimit: to_string(Keyword.get(instance, :background_upload_limit)), | |||
bannerlimit: to_string(Keyword.get(instance, :banner_upload_limit)) | |||
} | |||
data = %{ | |||
name: Keyword.get(instance, :name), | |||
description: Keyword.get(instance, :description), | |||
server: Web.base_url(), | |||
textlimit: to_string(Keyword.get(instance, :limit)), | |||
uploadlimit: uploadlimit, | |||
closed: bool_to_val(Keyword.get(instance, :registrations_open), "0", "1"), | |||
private: bool_to_val(Keyword.get(instance, :public, true), "0", "1"), | |||
vapidPublicKey: vapid_public_key, | |||
accountActivationRequired: | |||
bool_to_val(Keyword.get(instance, :account_activation_required, false)), | |||
invitesEnabled: bool_to_val(Keyword.get(instance, :invites_enabled, false)), | |||
safeDMMentionsEnabled: bool_to_val(Pleroma.Config.get([:instance, :safe_dm_mentions])) | |||
} | |||
managed_config = Keyword.get(instance, :managed_config) | |||
data = | |||
if managed_config do | |||
pleroma_fe = Pleroma.Config.get([:frontend_configurations, :pleroma_fe]) | |||
Map.put(data, "pleromafe", pleroma_fe) | |||
else | |||
data | |||
end | |||
json(conn, %{site: data}) | |||
end | |||
defp bool_to_val(true), do: "1" | |||
defp bool_to_val(_), do: "0" | |||
defp bool_to_val(true, val, _), do: val | |||
defp bool_to_val(_, _, val), do: val | |||
def frontend_configurations(conn, _params) do | |||
config = | |||
Pleroma.Config.get(:frontend_configurations, %{}) | |||
@@ -151,18 +89,6 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do | |||
json(conn, config) | |||
end | |||
def version(%{assigns: %{format: "xml"}} = conn, _params) do | |||
version = Pleroma.Application.named_version() | |||
conn | |||
|> put_resp_content_type("application/xml") | |||
|> send_resp(200, "<version>#{version}</version>") | |||
end | |||
def version(conn, _params) do | |||
json(conn, Pleroma.Application.named_version()) | |||
end | |||
def emoji(conn, _params) do | |||
emoji = | |||
Enum.reduce(Emoji.get_all(), %{}, fn {code, %Emoji{file: file, tags: tags}}, acc -> | |||
@@ -1 +1 @@ | |||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/vendors~app.18fea621d430000acc27.css rel=stylesheet><link href=/static/css/app.613cef07981cd95ccceb.css rel=stylesheet><link href=/static/fontello.1589385935077.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.561a1c605d1dfb0e6f74.js></script><script type=text/javascript src=/static/js/app.838ffa9aecf210c7d744.js></script></body></html> | |||
<!DOCTYPE html><html lang=en><head><meta charset=utf-8><meta name=viewport content="width=device-width,initial-scale=1,user-scalable=no"><title>Pleroma</title><!--server-generated-meta--><link rel=icon type=image/png href=/favicon.png><link href=/static/css/app.493b9b5acee37ba97824.css rel=stylesheet><link href=/static/fontello.1594134783339.css rel=stylesheet></head><body class=hidden><noscript>To use Pleroma, please enable JavaScript.</noscript><div id=app></div><script type=text/javascript src=/static/js/vendors~app.8837fb59589d1dd6acda.js></script><script type=text/javascript src=/static/js/app.53001fa190f37cf2743e.js></script></body></html> |
@@ -14,7 +14,6 @@ | |||
"logoMargin": ".1em", | |||
"logoMask": true, | |||
"minimalScopesMode": false, | |||
"noAttachmentLinks": false, | |||
"nsfwCensorImage": "", | |||
"postContentType": "text/plain", | |||
"redirectRootLogin": "/main/friends", | |||
@@ -22,6 +21,7 @@ | |||
"scopeCopy": true, | |||
"showFeaturesPanel": true, | |||
"showInstanceSpecificPanel": false, | |||
"sidebarRight": false, | |||
"subjectLineBehavior": "email", | |||
"theme": "pleroma-dark", | |||
"webPushNotifications": false | |||
@@ -0,0 +1,9 @@ | |||
.with-subscription-loading { | |||
padding: 10px; | |||
text-align: center; | |||
} | |||
.with-subscription-loading .error { | |||
font-size: 14px; | |||
} | |||
/*# sourceMappingURL=2.0778a6a864a1307a6c41.css.map*/ |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":["webpack:///./src/hocs/with_subscription/with_subscription.scss"],"names":[],"mappings":"AAAA;AACA;AACA;AACA;AACA;AACA;AACA,C","file":"static/css/2.0778a6a864a1307a6c41.css","sourcesContent":[".with-subscription-loading {\n padding: 10px;\n text-align: center;\n}\n.with-subscription-loading .error {\n font-size: 14px;\n}"],"sourceRoot":""} |
@@ -1,11 +1,11 @@ | |||
/*! | |||
* Cropper.js v1.5.6 | |||
* Cropper.js v1.4.3 | |||
* https://fengyuanchen.github.io/cropperjs | |||
* | |||
* Copyright 2015-present Chen Fengyuan | |||
* Released under the MIT license | |||
* | |||
* Date: 2019-10-04T04:33:44.164Z | |||
* Date: 2018-10-24T13:07:11.429Z | |||
*/ | |||
.cropper-container { | |||
@@ -16,6 +16,7 @@ | |||
-ms-touch-action: none; | |||
touch-action: none; | |||
-webkit-user-select: none; | |||
-moz-user-select: none; | |||
-ms-user-select: none; | |||
user-select: none; | |||
} | |||
@@ -55,14 +56,14 @@ | |||
.cropper-modal { | |||
background-color: #000; | |||
opacity: 0.5; | |||
opacity: .5; | |||
} | |||
.cropper-view-box { | |||
display: block; | |||
height: 100%; | |||
outline: 1px solid #39f; | |||
outline-color: rgba(51, 153, 255, 0.75); | |||
outline: 1px solid #39f; | |||
overflow: hidden; | |||
width: 100%; | |||
} | |||
@@ -70,7 +71,7 @@ | |||
.cropper-dashed { | |||
border: 0 dashed #eee; | |||
display: block; | |||
opacity: 0.5; | |||
opacity: .5; | |||
position: absolute; | |||
} | |||
@@ -96,28 +97,28 @@ | |||
display: block; | |||
height: 0; | |||
left: 50%; | |||
opacity: 0.75; | |||
opacity: .75; | |||
position: absolute; | |||
top: 50%; | |||
width: 0; | |||
} | |||
.cropper-center::before, | |||
.cropper-center::after { | |||
.cropper-center:before, | |||
.cropper-center:after { | |||
background-color: #eee; | |||
content: ' '; | |||
display: block; | |||
position: absolute; | |||
} | |||
.cropper-center::before { | |||
.cropper-center:before { | |||
height: 1px; | |||
left: -3px; | |||
top: 0; | |||
width: 7px; | |||
} | |||
.cropper-center::after { | |||
.cropper-center:after { | |||
height: 7px; | |||
left: 0; | |||
top: -3px; | |||
@@ -129,7 +130,7 @@ | |||
.cropper-point { | |||
display: block; | |||
height: 100%; | |||
opacity: 0.1; | |||
opacity: .1; | |||
position: absolute; | |||
width: 100%; | |||
} | |||
@@ -175,7 +176,7 @@ | |||
.cropper-point { | |||
background-color: #39f; | |||
height: 5px; | |||
opacity: 0.75; | |||
opacity: .75; | |||
width: 5px; | |||
} | |||
@@ -251,12 +252,12 @@ | |||
@media (min-width: 1200px) { | |||
.cropper-point.point-se { | |||
height: 5px; | |||
opacity: 0.75; | |||
opacity: .75; | |||
width: 5px; | |||
} | |||
} | |||
.cropper-point.point-se::before { | |||
.cropper-point.point-se:before { | |||
background-color: #39f; | |||
bottom: -50%; | |||
content: ' '; | |||
@@ -303,4 +304,4 @@ | |||
} | |||
/*# sourceMappingURL=vendors~app.18fea621d430000acc27.css.map*/ | |||
/*# sourceMappingURL=3.b2603a50868c68a1c192.css.map*/ |
@@ -0,0 +1,243 @@ | |||
.tab-switcher { | |||
display: -ms-flexbox; | |||
display: flex; | |||
} | |||
.tab-switcher .tab-icon { | |||
font-size: 2em; | |||
display: block; | |||
} | |||
.tab-switcher.top-tabs { | |||
-ms-flex-direction: column; | |||
flex-direction: column; | |||
} | |||
.tab-switcher.top-tabs > .tabs { | |||
width: 100%; | |||
overflow-y: hidden; | |||
overflow-x: auto; | |||
padding-top: 5px; | |||
-ms-flex-direction: row; | |||
flex-direction: row; | |||
} | |||
.tab-switcher.top-tabs > .tabs::after, .tab-switcher.top-tabs > .tabs::before { | |||
content: ""; | |||
-ms-flex: 1 1 auto; | |||
flex: 1 1 auto; | |||
border-bottom: 1px solid; | |||
border-bottom-color: #222; | |||
border-bottom-color: var(--border, #222); | |||
} | |||
.tab-switcher.top-tabs > .tabs .tab-wrapper { | |||
height: 28px; | |||
} | |||
.tab-switcher.top-tabs > .tabs .tab-wrapper:not(.active)::after { | |||
left: 0; | |||
right: 0; | |||
bottom: 0; | |||
border-bottom: 1px solid; | |||
border-bottom-color: #222; | |||
border-bottom-color: var(--border, #222); | |||
} | |||
.tab-switcher.top-tabs > .tabs .tab { | |||
width: 100%; | |||
min-width: 1px; | |||
border-bottom-left-radius: 0; | |||
border-bottom-right-radius: 0; | |||
padding-bottom: 99px; | |||
margin-bottom: -93px; | |||
} | |||
.tab-switcher.top-tabs .contents.scrollable-tabs { | |||
-ms-flex-preferred-size: 0; | |||
flex-basis: 0; | |||
} | |||
.tab-switcher.side-tabs { | |||
-ms-flex-direction: row; | |||
flex-direction: row; | |||
} | |||
@media all and (max-width: 800px) { | |||
.tab-switcher.side-tabs { | |||
overflow-x: auto; | |||
} | |||
} | |||
.tab-switcher.side-tabs > .contents { | |||
-ms-flex: 1 1 auto; | |||
flex: 1 1 auto; | |||
} | |||
.tab-switcher.side-tabs > .tabs { | |||
-ms-flex: 0 0 auto; | |||
flex: 0 0 auto; | |||
overflow-y: auto; | |||
overflow-x: hidden; | |||
-ms-flex-direction: column; | |||
flex-direction: column; | |||
} | |||
.tab-switcher.side-tabs > .tabs::after, .tab-switcher.side-tabs > .tabs::before { | |||
-ms-flex-negative: 0; | |||
flex-shrink: 0; | |||
-ms-flex-preferred-size: 0.5em; | |||
flex-basis: 0.5em; | |||
content: ""; | |||
border-right: 1px solid; | |||
border-right-color: #222; | |||
border-right-color: var(--border, #222); | |||
} | |||
.tab-switcher.side-tabs > .tabs::after { | |||
-ms-flex-positive: 1; | |||
flex-grow: 1; | |||
} | |||
.tab-switcher.side-tabs > .tabs::before { | |||
-ms-flex-positive: 0; | |||
flex-grow: 0; | |||
} | |||
.tab-switcher.side-tabs > .tabs .tab-wrapper { | |||
min-width: 10em; | |||
display: -ms-flexbox; | |||
display: flex; | |||
-ms-flex-direction: column; | |||
flex-direction: column; | |||
} | |||
@media all and (max-width: 800px) { | |||
.tab-switcher.side-tabs > .tabs .tab-wrapper { | |||
min-width: 1em; | |||
} | |||
} | |||
.tab-switcher.side-tabs > .tabs .tab-wrapper:not(.active)::after { | |||
top: 0; | |||
right: 0; | |||
bottom: 0; | |||
border-right: 1px solid; | |||
border-right-color: #222; | |||
border-right-color: var(--border, #222); | |||
} | |||
.tab-switcher.side-tabs > .tabs .tab-wrapper::before { | |||
-ms-flex: 0 0 6px; | |||
flex: 0 0 6px; | |||
content: ""; | |||
border-right: 1px solid; | |||
border-right-color: #222; | |||
border-right-color: var(--border, #222); | |||
} | |||
.tab-switcher.side-tabs > .tabs .tab-wrapper:last-child .tab { | |||
margin-bottom: 0; | |||
} | |||
.tab-switcher.side-tabs > .tabs .tab { | |||
-ms-flex: 1; | |||
flex: 1; | |||
box-sizing: content-box; | |||
min-width: 10em; | |||
min-width: 1px; | |||
border-top-right-radius: 0; | |||
border-bottom-right-radius: 0; | |||
padding-left: 1em; | |||
padding-right: calc(1em + 200px); | |||
margin-right: -200px; | |||
margin-left: 1em; | |||
} | |||
@media all and (max-width: 800px) { | |||
.tab-switcher.side-tabs > .tabs .tab { | |||
padding-left: 0.25em; | |||
padding-right: calc(.25em + 200px); | |||
margin-right: calc(.25em - 200px); | |||
margin-left: 0.25em; | |||
} | |||
.tab-switcher.side-tabs > .tabs .tab .text { | |||
display: none; | |||
} | |||
} | |||
.tab-switcher .contents { | |||
-ms-flex: 1 0 auto; | |||
flex: 1 0 auto; | |||
min-height: 0px; | |||
} | |||
.tab-switcher .contents .hidden { | |||
display: none; | |||
} | |||
.tab-switcher .contents .full-height:not(.hidden) { | |||
height: 100%; | |||
display: -ms-flexbox; | |||
display: flex; | |||
-ms-flex-direction: column; | |||
flex-direction: column; | |||
} | |||
.tab-switcher .contents .full-height:not(.hidden) > *:not(.mobile-label) { | |||
-ms-flex: 1; | |||
flex: 1; | |||
} | |||
.tab-switcher .contents.scrollable-tabs { | |||
overflow-y: auto; | |||
} | |||
.tab-switcher .tab { | |||
position: relative; | |||
white-space: nowrap; | |||
padding: 6px 1em; | |||
background-color: #182230; | |||
background-color: var(--tab, #182230); | |||
} | |||
.tab-switcher .tab, .tab-switcher .tab:active .tab-icon { | |||
color: #b9b9ba; | |||
color: var(--tabText, #b9b9ba); | |||
} | |||
.tab-switcher .tab:not(.active) { | |||
z-index: 4; | |||
} | |||
.tab-switcher .tab:not(.active):hover { | |||
z-index: 6; | |||
} | |||
.tab-switcher .tab.active { | |||
background: transparent; | |||
z-index: 5; | |||
color: #b9b9ba; | |||
color: var(--tabActiveText, #b9b9ba); | |||
} | |||
.tab-switcher .tab img { | |||
max-height: 26px; | |||
vertical-align: top; | |||
margin-top: -5px; | |||
} | |||
.tab-switcher .tabs { | |||
display: -ms-flexbox; | |||
display: flex; | |||
position: relative; | |||
box-sizing: border-box; | |||
} | |||
.tab-switcher .tabs::after, .tab-switcher .tabs::before { | |||
display: block; | |||
-ms-flex: 1 1 auto; | |||
flex: 1 1 auto; | |||
} | |||
.tab-switcher .tab-wrapper { | |||
position: relative; | |||
display: -ms-flexbox; | |||
display: flex; | |||
-ms-flex: 0 0 auto; | |||
flex: 0 0 auto; | |||
} | |||
.tab-switcher .tab-wrapper:not(.active)::after { | |||
content: ""; | |||
position: absolute; | |||
z-index: 7; | |||
} | |||
.tab-switcher .mobile-label { | |||
padding-left: 0.3em; | |||
padding-bottom: 0.25em; | |||
margin-top: 0.5em; | |||
margin-left: 0.2em; | |||
margin-bottom: 0.25em; | |||
border-bottom: 1px solid var(--border, #222); | |||
} | |||
@media all and (min-width: 800px) { | |||
.tab-switcher .mobile-label { | |||
display: none; | |||
} | |||
} | |||
.with-load-more-footer { | |||
padding: 10px; | |||
text-align: center; | |||
border-top: 1px solid; | |||
border-top-color: #222; | |||
border-top-color: var(--border, #222); | |||
} | |||
.with-load-more-footer .error { | |||
font-size: 14px; | |||
} | |||
/*# sourceMappingURL=app.493b9b5acee37ba97824.css.map*/ |
@@ -1,5 +0,0 @@ | |||
.with-load-more-footer{padding:10px;text-align:center;border-top:1px solid;border-top-color:#222;border-top-color:var(--border, #222)}.with-load-more-footer .error{font-size:14px} | |||
.tab-switcher{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.tab-switcher .contents{-ms-flex:1 0 auto;flex:1 0 auto;min-height:0px}.tab-switcher .contents .hidden{display:none}.tab-switcher .contents.scrollable-tabs{-ms-flex-preferred-size:0;flex-basis:0;overflow-y:auto}.tab-switcher .tabs{display:-ms-flexbox;display:flex;position:relative;width:100%;overflow-y:hidden;overflow-x:auto;padding-top:5px;box-sizing:border-box}.tab-switcher .tabs::after,.tab-switcher .tabs::before{display:block;content:"";-ms-flex:1 1 auto;flex:1 1 auto;border-bottom:1px solid;border-bottom-color:#222;border-bottom-color:var(--border, #222)}.tab-switcher .tabs .tab-wrapper{height:28px;position:relative;display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto}.tab-switcher .tabs .tab-wrapper .tab{width:100%;min-width:1px;position:relative;border-bottom-left-radius:0;border-bottom-right-radius:0;padding:6px 1em;padding-bottom:99px;margin-bottom:-93px;white-space:nowrap;color:#b9b9ba;color:var(--tabText, #b9b9ba);background-color:#182230;background-color:var(--tab, #182230)}.tab-switcher .tabs .tab-wrapper .tab:not(.active){z-index:4}.tab-switcher .tabs .tab-wrapper .tab:not(.active):hover{z-index:6}.tab-switcher .tabs .tab-wrapper .tab.active{background:transparent;z-index:5;color:#b9b9ba;color:var(--tabActiveText, #b9b9ba)}.tab-switcher .tabs .tab-wrapper .tab img{max-height:26px;vertical-align:top;margin-top:-5px}.tab-switcher .tabs .tab-wrapper:not(.active)::after{content:"";position:absolute;left:0;right:0;bottom:0;z-index:7;border-bottom:1px solid;border-bottom-color:#222;border-bottom-color:var(--border, #222)} | |||
.with-subscription-loading{padding:10px;text-align:center}.with-subscription-loading .error{font-size:14px} | |||
/*# sourceMappingURL=app.613cef07981cd95ccceb.css.map*/ |
@@ -1 +0,0 @@ | |||
{"version":3,"sources":["webpack:///./src/hocs/with_load_more/with_load_more.scss","webpack:///./src/components/tab_switcher/tab_switcher.scss","webpack:///./src/hocs/with_subscription/with_subscription.scss"],"names":[],"mappings":"AAAA,uBAAuB,aAAa,kBAAkB,qBAAqB,sBAAsB,qCAAqC,8BAA8B,e;ACApK,cAAc,oBAAoB,aAAa,0BAA0B,sBAAsB,wBAAwB,kBAAkB,cAAc,eAAe,gCAAgC,aAAa,wCAAwC,0BAA0B,aAAa,gBAAgB,oBAAoB,oBAAoB,aAAa,kBAAkB,WAAW,kBAAkB,gBAAgB,gBAAgB,sBAAsB,uDAAuD,cAAc,WAAW,kBAAkB,cAAc,wBAAwB,yBAAyB,wCAAwC,iCAAiC,YAAY,kBAAkB,oBAAoB,aAAa,kBAAkB,cAAc,sCAAsC,WAAW,cAAc,kBAAkB,4BAA4B,6BAA6B,gBAAgB,oBAAoB,oBAAoB,mBAAmB,cAAc,8BAA8B,yBAAyB,qCAAqC,mDAAmD,UAAU,yDAAyD,UAAU,6CAA6C,uBAAuB,UAAU,cAAc,oCAAoC,0CAA0C,gBAAgB,mBAAmB,gBAAgB,qDAAqD,WAAW,kBAAkB,OAAO,QAAQ,SAAS,UAAU,wBAAwB,yBAAyB,wC;ACAtlD,2BAA2B,aAAa,kBAAkB,kCAAkC,e","file":"static/css/app.613cef07981cd95ccceb.css","sourcesContent":[".with-load-more-footer{padding:10px;text-align:center;border-top:1px solid;border-top-color:#222;border-top-color:var(--border, #222)}.with-load-more-footer .error{font-size:14px}",".tab-switcher{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column}.tab-switcher .contents{-ms-flex:1 0 auto;flex:1 0 auto;min-height:0px}.tab-switcher .contents .hidden{display:none}.tab-switcher .contents.scrollable-tabs{-ms-flex-preferred-size:0;flex-basis:0;overflow-y:auto}.tab-switcher .tabs{display:-ms-flexbox;display:flex;position:relative;width:100%;overflow-y:hidden;overflow-x:auto;padding-top:5px;box-sizing:border-box}.tab-switcher .tabs::after,.tab-switcher .tabs::before{display:block;content:\"\";-ms-flex:1 1 auto;flex:1 1 auto;border-bottom:1px solid;border-bottom-color:#222;border-bottom-color:var(--border, #222)}.tab-switcher .tabs .tab-wrapper{height:28px;position:relative;display:-ms-flexbox;display:flex;-ms-flex:0 0 auto;flex:0 0 auto}.tab-switcher .tabs .tab-wrapper .tab{width:100%;min-width:1px;position:relative;border-bottom-left-radius:0;border-bottom-right-radius:0;padding:6px 1em;padding-bottom:99px;margin-bottom:-93px;white-space:nowrap;color:#b9b9ba;color:var(--tabText, #b9b9ba);background-color:#182230;background-color:var(--tab, #182230)}.tab-switcher .tabs .tab-wrapper .tab:not(.active){z-index:4}.tab-switcher .tabs .tab-wrapper .tab:not(.active):hover{z-index:6}.tab-switcher .tabs .tab-wrapper .tab.active{background:transparent;z-index:5;color:#b9b9ba;color:var(--tabActiveText, #b9b9ba)}.tab-switcher .tabs .tab-wrapper .tab img{max-height:26px;vertical-align:top;margin-top:-5px}.tab-switcher .tabs .tab-wrapper:not(.active)::after{content:\"\";position:absolute;left:0;right:0;bottom:0;z-index:7;border-bottom:1px solid;border-bottom-color:#222;border-bottom-color:var(--border, #222)}",".with-subscription-loading{padding:10px;text-align:center}.with-subscription-loading .error{font-size:14px}"],"sourceRoot":""} |
@@ -80,8 +80,16 @@ | |||
<glyph glyph-name="user" unicode="" d="M714 76q0-60-35-104t-84-44h-476q-49 0-84 44t-35 104q0 48 5 90t17 85 33 73 52 50 76 19q73-72 174-72t175 72q42 0 75-19t52-50 33-73 18-85 4-90z m-143 495q0-88-62-151t-152-63-151 63-63 151 63 152 151 63 152-63 62-152z" horiz-adv-x="714.3" /> | |||
<glyph glyph-name="download" unicode="" d="M714 107q0 15-10 25t-25 11-25-11-11-25 11-25 25-11 25 11 10 25z m143 0q0 15-10 25t-26 11-25-11-10-25 10-25 25-11 26 11 10 25z m72 125v-179q0-22-16-37t-38-16h-821q-23 0-38 16t-16 37v179q0 22 16 38t38 16h259l75-76q33-32 76-32t76 32l76 76h259q22 0 38-16t16-38z m-182 318q10-23-8-39l-250-250q-10-11-25-11t-25 11l-250 250q-17 16-8 39 10 21 33 21h143v250q0 15 11 25t25 11h143q14 0 25-11t10-25v-250h143q24 0 33-21z" horiz-adv-x="928.6" /> | |||
<glyph glyph-name="bookmark" unicode="" d="M650 786q12 0 24-5 19-8 29-23t11-35v-719q0-19-11-35t-29-23q-10-4-24-4-27 0-47 18l-246 236-246-236q-20-19-46-19-13 0-25 5-18 7-29 23t-11 35v719q0 19 11 35t29 23q12 5 25 5h585z" horiz-adv-x="714.3" /> | |||
<glyph glyph-name="ok" unicode="" d="M933 541q0-22-16-38l-404-404-76-76q-16-15-38-15t-38 15l-76 76-202 202q-15 16-15 38t15 38l76 76q16 16 38 16t38-16l164-165 366 367q16 16 38 16t38-16l76-76q16-15 16-38z" horiz-adv-x="1000" /> | |||
<glyph glyph-name="music" unicode="" d="M857 732v-625q0-28-19-50t-48-33-58-18-53-6-54 6-58 18-48 33-19 50 19 50 48 33 58 18 54 6q58 0 107-22v300l-429-132v-396q0-28-19-50t-48-33-58-18-53-6-54 6-58 18-48 33-19 50 19 50 48 34 58 17 54 6q58 0 107-21v539q0 17 10 32t28 20l464 142q7 3 16 3 22 0 38-16t15-38z" horiz-adv-x="857.1" /> | |||
<glyph glyph-name="doc" unicode="" d="M819 645q16-16 27-42t11-50v-642q0-23-15-38t-38-16h-750q-23 0-38 16t-16 38v892q0 23 16 38t38 16h500q22 0 49-11t42-27z m-248 136v-210h210q-5 17-12 23l-175 175q-6 7-23 12z m215-853v572h-232q-23 0-38 16t-16 37v233h-429v-858h715z" horiz-adv-x="857.1" /> | |||
<glyph glyph-name="spin3" unicode="" d="M494 857c-266 0-483-210-494-472-1-19 13-20 13-20l84 0c16 0 19 10 19 18 10 199 176 358 378 358 107 0 205-45 273-118l-58-57c-11-12-11-27 5-31l247-50c21-5 46 11 37 44l-58 227c-2 9-16 22-29 13l-65-60c-89 91-214 148-352 148z m409-508c-16 0-19-10-19-18-10-199-176-358-377-358-108 0-205 45-274 118l59 57c10 12 10 27-5 31l-248 50c-21 5-46-11-37-44l58-227c2-9 16-22 30-13l64 60c89-91 214-148 353-148 265 0 482 210 493 473 1 18-13 19-13 19l-84 0z" horiz-adv-x="1000" /> | |||
<glyph glyph-name="spin4" unicode="" d="M498 857c-114 0-228-39-320-116l0 0c173 140 428 130 588-31 134-134 164-332 89-495-10-29-5-50 12-68 21-20 61-23 84 0 3 3 12 15 15 24 71 180 33 393-112 539-99 98-228 147-356 147z m-409-274c-14 0-29-5-39-16-3-3-13-15-15-24-71-180-34-393 112-539 185-185 479-195 676-31l0 0c-173-140-428-130-589 31-134 134-163 333-89 495 11 29 6 50-12 68-11 11-27 17-44 16z" horiz-adv-x="1001" /> | |||
@@ -90,6 +98,10 @@ | |||
<glyph glyph-name="link-ext-alt" unicode="" d="M714 339v268q0 15-10 25t-25 11h-268q-24 0-33-22-10-23 8-39l80-80-298-298q-11-11-11-26t11-25l57-57q11-10 25-10t25 10l298 298 81-80q10-11 25-11 6 0 14 3 21 10 21 33z m143 286v-536q0-66-47-113t-114-48h-535q-67 0-114 48t-47 113v536q0 66 47 113t114 48h535q67 0 114-48t47-113z" horiz-adv-x="857.1" /> | |||
<glyph glyph-name="bookmark-empty" unicode="" d="M643 714h-572v-693l237 227 49 47 50-47 236-227v693z m7 72q12 0 24-5 19-8 29-23t11-35v-719q0-19-11-35t-29-23q-10-4-24-4-27 0-47 18l-246 236-246-236q-20-19-46-19-13 0-25 5-18 7-29 23t-11 35v719q0 19 11 35t29 23q12 5 25 5h585z" horiz-adv-x="714.3" /> | |||
<glyph glyph-name="filter" unicode="" d="M783 692q9-22-8-39l-275-275v-414q0-23-22-33-7-3-14-3-15 0-25 11l-143 143q-10 11-10 25v271l-275 275q-18 17-8 39 9 22 33 22h714q23 0 33-22z" horiz-adv-x="785.7" /> | |||
<glyph glyph-name="menu" unicode="" d="M857 107v-71q0-15-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 25t25 11h785q15 0 26-11t10-25z m0 286v-72q0-14-10-25t-26-10h-785q-15 0-25 10t-11 25v72q0 14 11 25t25 10h785q15 0 26-10t10-25z m0 285v-71q0-14-10-25t-26-11h-785q-15 0-25 11t-11 25v71q0 15 11 26t25 10h785q15 0 26-10t10-26z" horiz-adv-x="857.1" /> | |||
<glyph glyph-name="mail-alt" unicode="" d="M1000 461v-443q0-37-26-63t-63-27h-822q-36 0-63 27t-26 63v443q25-27 56-49 202-137 278-192 32-24 51-37t53-27 61-13h2q28 0 61 13t53 27 51 37q95 68 278 192 32 22 56 49z m0 164q0-44-27-84t-68-69q-210-146-262-181-5-4-23-17t-30-22-29-18-32-15-28-5h-2q-12 0-27 5t-32 15-30 18-30 22-23 17q-51 35-147 101t-114 80q-35 23-65 64t-31 77q0 43 23 72t66 29h822q36 0 63-26t26-63z" horiz-adv-x="1000" /> |
@@ -0,0 +1,152 @@ | |||
@font-face { | |||
font-family: "Icons"; | |||
src: url("./font/fontello.1594030805019.eot"); | |||
src: url("./font/fontello.1594030805019.eot") format("embedded-opentype"), | |||
url("./font/fontello.1594030805019.woff2") format("woff2"), | |||
url("./font/fontello.1594030805019.woff") format("woff"), | |||
url("./font/fontello.1594030805019.ttf") format("truetype"), | |||
url("./font/fontello.1594030805019.svg") format("svg"); | |||
font-weight: normal; | |||
font-style: normal; | |||
} | |||
[class^="icon-"]::before, | |||
[class*=" icon-"]::before { | |||
font-family: "Icons"; | |||
font-style: normal; | |||
font-weight: normal; | |||
speak: none; | |||
display: inline-block; | |||
text-decoration: inherit; | |||
width: 1em; | |||
margin-right: .2em; | |||
text-align: center; | |||
font-variant: normal; | |||
text-transform: none; | |||
line-height: 1em; | |||
margin-left: .2em; | |||
-webkit-font-smoothing: antialiased; | |||
-moz-osx-font-smoothing: grayscale; | |||
} | |||
.icon-spin4::before { content: "\e834"; } | |||
.icon-cancel::before { content: "\e800"; } | |||
.icon-upload::before { content: "\e801"; } | |||
.icon-spin3::before { content: "\e832"; } | |||
.icon-reply::before { content: "\f112"; } | |||
.icon-star::before { content: "\e802"; } | |||
.icon-star-empty::before { content: "\e803"; } | |||
.icon-retweet::before { content: "\e804"; } | |||
.icon-eye-off::before { content: "\e805"; } | |||
.icon-binoculars::before { content: "\f1e5"; } | |||
.icon-cog::before { content: "\e807"; } | |||
.icon-user-plus::before { content: "\f234"; } | |||
.icon-menu::before { content: "\f0c9"; } | |||
.icon-logout::before { content: "\e808"; } | |||
.icon-down-open::before { content: "\e809"; } | |||
.icon-attach::before { content: "\e80a"; } | |||
.icon-link-ext::before { content: "\f08e"; } | |||
.icon-link-ext-alt::before { content: "\f08f"; } | |||
.icon-picture::before { content: "\e80b"; } | |||
.icon-video::before { content: "\e80c"; } | |||
.icon-right-open::before { content: "\e80d"; } | |||
.icon-left-open::before { content: "\e80e"; } | |||
.icon-up-open::before { content: "\e80f"; } | |||
.icon-comment-empty::before { content: "\f0e5"; } | |||
.icon-mail-alt::before { content: "\f0e0"; } | |||
.icon-lock::before { content: "\e811"; } | |||
.icon-lock-open-alt::before { content: "\f13e"; } | |||
.icon-globe::before { content: "\e812"; } | |||
.icon-brush::before { content: "\e813"; } | |||
.icon-search::before { content: "\e806"; } | |||
.icon-adjust::before { content: "\e816"; } | |||
.icon-thumbs-up-alt::before { content: "\f164"; } | |||
.icon-attention::before { content: "\e814"; } | |||
.icon-plus-squared::before { content: "\f0fe"; } | |||
.icon-plus::before { content: "\e815"; } | |||
.icon-edit::before { content: "\e817"; } | |||
.icon-play-circled::before { content: "\f144"; } | |||
.icon-pencil::before { content: "\e818"; } | |||
.icon-chart-bar::before { content: "\e81b"; } | |||
.icon-smile::before { content: "\f118"; } | |||
.icon-bell-alt::before { content: "\f0f3"; } | |||
.icon-wrench::before { content: "\e81a"; } | |||
.icon-pin::before { content: "\e819"; } | |||
.icon-ellipsis::before { content: "\f141"; } | |||
.icon-bell-ringing-o::before { content: "\e810"; } | |||
.icon-zoom-in::before { content: "\e81c"; } | |||
.icon-gauge::before { content: "\f0e4"; } | |||
.icon-users::before { content: "\e81d"; } | |||
.icon-info-circled::before { content: "\e81f"; } | |||
.icon-home-2::before { content: "\e821"; } | |||
.icon-chat::before { content: "\e81e"; } | |||
.icon-login::before { content: "\e820"; } | |||
.icon-arrow-curved::before { content: "\e822"; } | |||
.icon-link::before { content: "\e823"; } | |||
.icon-share::before { content: "\f1e0"; } | |||
.icon-user::before { content: "\e824"; } | |||
.icon-ok::before { content: "\e827"; } | |||
.icon-filter::before { content: "\f0b0"; } | |||
.icon-download::before { content: "\e825"; } | |||
.icon-bookmark::before { content: "\e826"; } | |||
.icon-bookmark-empty::before { content: "\f097"; } |
@@ -0,0 +1,156 @@ | |||
@font-face { | |||
font-family: "Icons"; | |||
src: url("./font/fontello.1594134783339.eot"); | |||
src: url("./font/fontello.1594134783339.eot") format("embedded-opentype"), | |||
url("./font/fontello.1594134783339.woff2") format("woff2"), | |||
url("./font/fontello.1594134783339.woff") format("woff"), | |||
url("./font/fontello.1594134783339.ttf") format("truetype"), | |||
url("./font/fontello.1594134783339.svg") format("svg"); | |||
font-weight: normal; | |||
font-style: normal; | |||
} | |||
[class^="icon-"]::before, | |||
[class*=" icon-"]::before { | |||
font-family: "Icons"; | |||
font-style: normal; | |||
font-weight: normal; | |||
speak: none; | |||
display: inline-block; | |||
text-decoration: inherit; | |||
width: 1em; | |||
margin-right: .2em; | |||
text-align: center; | |||
font-variant: normal; | |||
text-transform: none; | |||
line-height: 1em; | |||
margin-left: .2em; | |||
-webkit-font-smoothing: antialiased; | |||
-moz-osx-font-smoothing: grayscale; | |||
} | |||
.icon-spin4::before { content: "\e834"; } | |||
.icon-cancel::before { content: "\e800"; } | |||
.icon-upload::before { content: "\e801"; } | |||
.icon-spin3::before { content: "\e832"; } | |||
.icon-reply::before { content: "\f112"; } | |||
.icon-star::before { content: "\e802"; } | |||
.icon-star-empty::before { content: "\e803"; } | |||
.icon-retweet::before { content: "\e804"; } | |||
.icon-eye-off::before { content: "\e805"; } | |||
.icon-binoculars::before { content: "\f1e5"; } | |||
.icon-cog::before { content: "\e807"; } | |||
.icon-user-plus::before { content: "\f234"; } | |||
.icon-menu::before { content: "\f0c9"; } | |||
.icon-logout::before { content: "\e808"; } | |||
.icon-down-open::before { content: "\e809"; } | |||
.icon-attach::before { content: "\e80a"; } | |||
.icon-link-ext::before { content: "\f08e"; } | |||
.icon-link-ext-alt::before { content: "\f08f"; } | |||
.icon-picture::before { content: "\e80b"; } | |||
.icon-video::before { content: "\e80c"; } | |||
.icon-right-open::before { content: "\e80d"; } | |||
.icon-left-open::before { content: "\e80e"; } | |||
.icon-up-open::before { content: "\e80f"; } | |||
.icon-comment-empty::before { content: "\f0e5"; } | |||
.icon-mail-alt::before { content: "\f0e0"; } | |||
.icon-lock::before { content: "\e811"; } | |||
.icon-lock-open-alt::before { content: "\f13e"; } | |||
.icon-globe::before { content: "\e812"; } | |||
.icon-brush::before { content: "\e813"; } | |||
.icon-search::before { content: "\e806"; } | |||
.icon-adjust::before { content: "\e816"; } | |||
.icon-thumbs-up-alt::before { content: "\f164"; } | |||
.icon-attention::before { content: "\e814"; } | |||
.icon-plus-squared::before { content: "\f0fe"; } | |||
.icon-plus::before { content: "\e815"; } | |||
.icon-edit::before { content: "\e817"; } | |||
.icon-play-circled::before { content: "\f144"; } | |||
.icon-pencil::before { content: "\e818"; } | |||
.icon-chart-bar::before { content: "\e81b"; } | |||
.icon-smile::before { content: "\f118"; } | |||
.icon-bell-alt::before { content: "\f0f3"; } | |||
.icon-wrench::before { content: "\e81a"; } | |||
.icon-pin::before { content: "\e819"; } | |||
.icon-ellipsis::before { content: "\f141"; } | |||
.icon-bell-ringing-o::before { content: "\e810"; } | |||
.icon-zoom-in::before { content: "\e81c"; } | |||
.icon-gauge::before { content: "\f0e4"; } | |||
.icon-users::before { content: "\e81d"; } | |||
.icon-info-circled::before { content: "\e81f"; } | |||
.icon-home-2::before { content: "\e821"; } | |||
.icon-chat::before { content: "\e81e"; } | |||
.icon-login::before { content: "\e820"; } | |||
.icon-arrow-curved::before { content: "\e822"; } | |||
.icon-link::before { content: "\e823"; } | |||
.icon-share::before { content: "\f1e0"; } | |||
.icon-user::before { content: "\e824"; } | |||
.icon-ok::before { content: "\e827"; } | |||
.icon-filter::before { content: "\f0b0"; } | |||
.icon-download::before { content: "\e825"; } | |||
.icon-bookmark::before { content: "\e826"; } | |||
.icon-bookmark-empty::before { content: "\f097"; } | |||
.icon-music::before { content: "\e828"; } | |||
.icon-doc::before { content: "\e829"; } |
@@ -363,6 +363,42 @@ | |||
"css": "ok", | |||
"code": 59431, | |||
"src": "fontawesome" | |||
}, | |||
{ | |||
"uid": "4109c474ff99cad28fd5a2c38af2ec6f", | |||
"css": "filter", | |||
"code": 61616, | |||
"src": "fontawesome" | |||
}, | |||
{ | |||
"uid": "9a76bc135eac17d2c8b8ad4a5774fc87", | |||
"css": "download", | |||
"code": 59429, | |||
"src": "fontawesome" | |||
}, | |||
{ | |||
"uid": "f04a5d24e9e659145b966739c4fde82a", | |||
"css": "bookmark", | |||
"code": 59430, | |||
"src": "fontawesome" | |||
}, | |||
{ | |||
"uid": "2f5ef6f6b7aaebc56458ab4e865beff5", | |||
"css": "bookmark-empty", | |||
"code": 61591, | |||
"src": "fontawesome" | |||
}, | |||
{ | |||
"uid": "9ea0a737ccc45d6c510dcbae56058849", | |||
"css": "music", | |||
"code": 59432, | |||
"src": "fontawesome" | |||
}, | |||
{ | |||
"uid": "1b5a5d7b7e3c71437f5a26befdd045ed", | |||
"css": "doc", | |||
"code": 59433, | |||
"src": "fontawesome" | |||
} | |||
] | |||
} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/10.4a22c77e34edcd678d2f.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/11.787aa24e4fd5caef9adb.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/12.35a510cf14233f0c6e1f.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/13.7931a609d62a42678085.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/14.cc092634462fd2a4cfbc.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/15.e9ddc5dfd38426398e00.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/16.476e7809b8593264469e.js","sourceRoot":""} |
@@ -0,0 +1,2 @@ | |||
(window.webpackJsonp=window.webpackJsonp||[]).push([[17],{550:function(e){e.exports={finder:{error_fetching_user:"Hiba felhasználó beszerzésével",find_user:"Felhasználó keresése"},general:{submit:"Elküld"},login:{login:"Bejelentkezés",logout:"Kijelentkezés",password:"Jelszó",placeholder:"e.g. lain",register:"Feliratkozás",username:"Felhasználó név"},nav:{mentions:"Említéseim",public_tl:"Publikus Idővonal",timeline:"Idővonal",twkn:"Az Egész Ismert Hálózat"},notifications:{followed_you:"követ téged",notifications:"Értesítések",read:"Olvasva!"},post_status:{default:"Most érkeztem L.A.-be",posting:"Küldés folyamatban"},registration:{bio:"Bio",email:"Email",fullname:"Teljes név",password_confirm:"Jelszó megerősítése",registration:"Feliratkozás"},settings:{attachments:"Csatolmányok",autoload:"Autoatikus betöltés engedélyezése lap aljára görgetéskor",avatar:"Avatár",bio:"Bio",current_avatar:"Jelenlegi avatár",current_profile_banner:"Jelenlegi profil banner",filtering:"Szűrés",filtering_explanation:"Minden tartalom mely ezen szavakat tartalmazza némítva lesz, soronként egy",hide_attachments_in_convo:"Csatolmányok elrejtése a társalgásokban",hide_attachments_in_tl:"Csatolmányok elrejtése az idővonalon",name:"Név",name_bio:"Név és Bio",nsfw_clickthrough:"NSFW átkattintási tartalom elrejtésének engedélyezése",profile_background:"Profil háttérkép",profile_banner:"Profil Banner",reply_link_preview:"Válasz-link előzetes mutatása egér rátételkor",set_new_avatar:"Új avatár",set_new_profile_background:"Új profil háttér beállítása",set_new_profile_banner:"Új profil banner",settings:"Beállítások",theme:"Téma",user_settings:"Felhasználói beállítások"},timeline:{conversation:"Társalgás",error_fetching:"Hiba a frissítések beszerzésénél",load_older:"Régebbi állapotok betöltése",show_new:"Újak mutatása",up_to_date:"Naprakész"},user_card:{block:"Letilt",blocked:"Letiltva!",follow:"Követ",followees:"Követettek",followers:"Követők",following:"Követve!",follows_you:"Követ téged!",mute:"Némít",muted:"Némított",per_day:"naponta",statuses:"Állapotok"}}}}]); | |||
//# sourceMappingURL=17.acbe4c09f05ae56c76a2.js.map |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/17.acbe4c09f05ae56c76a2.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/18.a8ccd7f2a47c5c94b3b9.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/19.5894e9c12b4fd5e45872.js","sourceRoot":""} |
@@ -1,2 +0,0 @@ | |||
(window.webpackJsonp=window.webpackJsonp||[]).push([[2],{587:function(t,e,i){var c=i(588);"string"==typeof c&&(c=[[t.i,c,""]]),c.locals&&(t.exports=c.locals);(0,i(3).default)("2eec4758",c,!0,{})},588:function(t,e,i){(t.exports=i(2)(!1)).push([t.i,".sticker-picker{width:100%}.sticker-picker .contents{min-height:250px}.sticker-picker .contents .sticker-picker-content{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:0 4px}.sticker-picker .contents .sticker-picker-content .sticker{display:-ms-flexbox;display:flex;-ms-flex:1 1 auto;flex:1 1 auto;margin:4px;width:56px;height:56px}.sticker-picker .contents .sticker-picker-content .sticker img{height:100%}.sticker-picker .contents .sticker-picker-content .sticker img:hover{filter:drop-shadow(0 0 5px var(--accent,#d8a070))}",""])},589:function(t,e,i){"use strict";i.r(e);var c=i(91),n={components:{TabSwitcher:i(53).a},data:function(){return{meta:{stickers:[]},path:""}},computed:{pack:function(){return this.$store.state.instance.stickers||[]}},methods:{clear:function(){this.meta={stickers:[]}},pick:function(t,e){var i=this,n=this.$store;fetch(t).then((function(t){t.blob().then((function(t){var a=new File([t],e,{mimetype:"image/png"}),r=new FormData;r.append("file",a),c.a.uploadMedia({store:n,formData:r}).then((function(t){i.$emit("uploaded",t),i.clear()}),(function(t){console.warn("Can't attach sticker"),console.warn(t),i.$emit("upload-failed","default")}))}))}))}}},a=i(0);var r=function(t){i(587)},s=Object(a.a)(n,(function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",{staticClass:"sticker-picker"},[i("tab-switcher",{staticClass:"tab-switcher",attrs:{"render-only-focused":!0,"scrollable-tabs":""}},t._l(t.pack,(function(e){return i("div",{key:e.path,staticClass:"sticker-picker-content",attrs:{"image-tooltip":e.meta.title,image:e.path+e.meta.tabIcon}},t._l(e.meta.stickers,(function(c){return i("div",{key:c,staticClass:"sticker",on:{click:function(i){return i.stopPropagation(),i.preventDefault(),t.pick(e.path+c,e.meta.title)}}},[i("img",{attrs:{src:e.path+c}})])})),0)})),0)],1)}),[],!1,r,null,null);e.default=s.exports}}]); | |||
//# sourceMappingURL=2.18e4adec273c4ce867a8.js.map |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/20.43b5b27b0f68474f3b72.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/21.72b45b01be9d0f4c62ce.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/22.26f13a22ad57a0d14670.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/23.91a60b775352a806f887.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/24.c8d8438aac954d4707ac.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/25.79ac9e020d571b67f02a.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/26.3af8f54349f672f2c7c8.js","sourceRoot":""} |
@@ -0,0 +1,2 @@ | |||
(window.webpackJsonp=window.webpackJsonp||[]).push([[27],{560:function(e){e.exports={finder:{error_fetching_user:"Eroare la preluarea utilizatorului",find_user:"Găsește utilizator"},general:{submit:"trimite"},login:{login:"Loghează",logout:"Deloghează",password:"Parolă",placeholder:"d.e. lain",register:"Înregistrare",username:"Nume utilizator"},nav:{mentions:"Menționări",public_tl:"Cronologie Publică",timeline:"Cronologie",twkn:"Toată Reșeaua Cunoscută"},notifications:{followed_you:"te-a urmărit",notifications:"Notificări",read:"Citit!"},post_status:{default:"Nu de mult am aterizat în L.A.",posting:"Postează"},registration:{bio:"Bio",email:"Email",fullname:"Numele întreg",password_confirm:"Cofirmă parola",registration:"Îregistrare"},settings:{attachments:"Atașamente",autoload:"Permite încărcarea automată când scrolat la capăt",avatar:"Avatar",bio:"Bio",current_avatar:"Avatarul curent",current_profile_banner:"Bannerul curent al profilului",filtering:"Filtru",filtering_explanation:"Toate stările care conțin aceste cuvinte vor fi puse pe mut, una pe linie",hide_attachments_in_convo:"Ascunde atașamentele în conversații",hide_attachments_in_tl:"Ascunde atașamentele în cronologie",name:"Nume",name_bio:"Nume și Bio",nsfw_clickthrough:"Permite ascunderea al atașamentelor NSFW",profile_background:"Fundalul de profil",profile_banner:"Banner de profil",reply_link_preview:"Permite previzualizarea linkului de răspuns la planarea de mouse",set_new_avatar:"Setează avatar nou",set_new_profile_background:"Setează fundal nou",set_new_profile_banner:"Setează banner nou la profil",settings:"Setări",theme:"Temă",user_settings:"Setările utilizatorului"},timeline:{conversation:"Conversație",error_fetching:"Erare la preluarea actualizărilor",load_older:"Încarcă stări mai vechi",show_new:"Arată cele noi",up_to_date:"La zi"},user_card:{block:"Blochează",blocked:"Blocat!",follow:"Urmărește",followees:"Urmărește",followers:"Următori",following:"Urmărit!",follows_you:"Te urmărește!",mute:"Pune pe mut",muted:"Pus pe mut",per_day:"pe zi",statuses:"Stări"}}}}]); | |||
//# sourceMappingURL=27.51287d408313da67b0b8.js.map |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/27.51287d408313da67b0b8.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/28.be5118beb1098a81332d.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/29.084f6fb0987d3862d410.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/30.6e6d63411def2e175d11.js","sourceRoot":""} |
@@ -0,0 +1,2 @@ | |||
(window.webpackJsonp=window.webpackJsonp||[]).push([[4],{564:function(t,e,i){var c=i(565);"string"==typeof c&&(c=[[t.i,c,""]]),c.locals&&(t.exports=c.locals);(0,i(4).default)("cc6cdea4",c,!0,{})},565:function(t,e,i){(t.exports=i(3)(!1)).push([t.i,".sticker-picker{width:100%}.sticker-picker .contents{min-height:250px}.sticker-picker .contents .sticker-picker-content{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;padding:0 4px}.sticker-picker .contents .sticker-picker-content .sticker{display:-ms-flexbox;display:flex;-ms-flex:1 1 auto;flex:1 1 auto;margin:4px;width:56px;height:56px}.sticker-picker .contents .sticker-picker-content .sticker img{height:100%}.sticker-picker .contents .sticker-picker-content .sticker img:hover{filter:drop-shadow(0 0 5px var(--accent,#d8a070))}",""])},617:function(t,e,i){"use strict";i.r(e);var c=i(55),n={components:{TabSwitcher:i(130).a},data:function(){return{meta:{stickers:[]},path:""}},computed:{pack:function(){return this.$store.state.instance.stickers||[]}},methods:{clear:function(){this.meta={stickers:[]}},pick:function(t,e){var i=this,n=this.$store;fetch(t).then(function(t){t.blob().then(function(t){var a=new File([t],e,{mimetype:"image/png"}),r=new FormData;r.append("file",a),c.a.uploadMedia({store:n,formData:r}).then(function(t){i.$emit("uploaded",t),i.clear()},function(t){console.warn("Can't attach sticker"),console.warn(t),i.$emit("upload-failed","default")})})})}}},a=i(0);var r=function(t){i(564)},s=Object(a.a)(n,function(){var t=this,e=t.$createElement,i=t._self._c||e;return i("div",{staticClass:"sticker-picker"},[i("tab-switcher",{staticClass:"tab-switcher",attrs:{"render-only-focused":!0,"scrollable-tabs":""}},t._l(t.pack,function(e){return i("div",{key:e.path,staticClass:"sticker-picker-content",attrs:{"image-tooltip":e.meta.title,image:e.path+e.meta.tabIcon}},t._l(e.meta.stickers,function(c){return i("div",{key:c,staticClass:"sticker",on:{click:function(i){return i.stopPropagation(),i.preventDefault(),t.pick(e.path+c,e.meta.title)}}},[i("img",{attrs:{src:e.path+c}})])}),0)}),0)],1)},[],!1,r,null,null);e.default=s.exports}}]); | |||
//# sourceMappingURL=4.c3f92d0b6ff90b36e3f5.js.map |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/5.d30e50cd5c52d54ffdc9.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/6.fa6d5c2d85d44f0ba121.js","sourceRoot":""} |
@@ -0,0 +1 @@ | |||
{"version":3,"sources":[],"names":[],"mappings":"","file":"static/js/7.d558a086622f668601a6.js","sourceRoot":""} |