Merge branch 'develop' of git.pleroma.social:pleroma/pleroma into remake-remodel-dms

This commit is contained in:
lain 2020-05-21 15:00:05 +02:00
commit 814c3e5171
570 changed files with 3509 additions and 2461 deletions

View File

@ -15,6 +15,7 @@ The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/).
- **Breaking:** removed `with_move` parameter from notifications timeline.
### Added
- Instance: Add `background_image` to configuration and `/api/v1/instance`
- Instance: Extend `/api/v1/instance` with Pleroma-specific information.
- NodeInfo: `pleroma:api/v1/notifications:include_types_filter` to the `features` list.
- NodeInfo: `pleroma_emoji_reactions` to the `features` list.

View File

@ -183,6 +183,7 @@ config :pleroma, :instance,
email: "example@example.com",
notify_email: "noreply@example.com",
description: "A Pleroma instance, an alternative fediverse server",
background_image: "/images/city.jpg",
limit: 5_000,
chat_limit: 5_000,
remote_limit: 100_000,
@ -271,20 +272,33 @@ config :pleroma, :markup,
config :pleroma, :frontend_configurations,
pleroma_fe: %{
theme: "pleroma-dark",
logo: "/static/logo.png",
background: "/images/city.jpg",
redirectRootNoLogin: "/main/all",
redirectRootLogin: "/main/friends",
showInstanceSpecificPanel: true,
scopeOptionsEnabled: false,
formattingOptionsEnabled: false,
alwaysShowSubjectInput: true,
background: "/static/aurora_borealis.jpg",
collapseMessageWithSubject: false,
disableChat: false,
greentext: false,
hideFilteredStatuses: false,
hideMutedPosts: false,
hidePostStats: false,
hideSitename: false,
hideUserStats: false,
loginMethod: "password",
logo: "/static/logo.png",
logoMargin: ".1em",
logoMask: true,
minimalScopesMode: false,
noAttachmentLinks: false,
nsfwCensorImage: "",
postContentType: "text/plain",
redirectRootLogin: "/main/friends",
redirectRootNoLogin: "/main/all",
scopeCopy: true,
sidebarRight: false,
showFeaturesPanel: true,
showInstanceSpecificPanel: false,
subjectLineBehavior: "email",
alwaysShowSubjectInput: true
theme: "pleroma-dark",
webPushNotifications: false
},
masto_fe: %{
showInstanceSpecificPanel: true
@ -376,6 +390,10 @@ config :pleroma, :rich_media,
config :pleroma, :media_proxy,
enabled: false,
invalidation: [
enabled: false,
provider: Pleroma.Web.MediaProxy.Invalidation.Script
],
proxy_opts: [
redirect_on_failure: false,
max_body_length: 25 * 1_048_576,

View File

@ -1117,6 +1117,7 @@ config :pleroma, :config_description, [
redirectRootLogin: "/main/friends",
redirectRootNoLogin: "/main/all",
scopeCopy: true,
sidebarRight: false,
showFeaturesPanel: true,
showInstanceSpecificPanel: false,
subjectLineBehavior: "email",
@ -1256,6 +1257,12 @@ config :pleroma, :config_description, [
type: :boolean,
description: "Copy the scope (private/unlisted/public) in replies to posts by default"
},
%{
key: :sidebarRight,
label: "Sidebar on Right",
type: :boolean,
description: "Change alignment of sidebar and panels to the right."
},
%{
key: :showFeaturesPanel,
label: "Show instance features panel",

View File

@ -216,6 +216,7 @@ Has theses additional parameters (which are the same as in Pleroma-API):
- `avatar_upload_limit`: The same for avatars
- `background_upload_limit`: The same for backgrounds
- `banner_upload_limit`: The same for banners
- `background_image`: A background image that frontends can use
- `pleroma.metadata.features`: A list of supported features
- `pleroma.metadata.federation`: The federation restrictions of this instance
- `vapid_public_key`: The public key needed for push messages

View File

@ -265,7 +265,7 @@ See [Admin-API](admin_api.md)
* Method `PUT`
* Authentication: required
* Params:
* `image`: Multipart image
* `file`: Multipart image
* Response: JSON. Returns a mastodon media attachment entity
when successful, otherwise returns HTTP 415 `{"error": "error_msg"}`
* Example response:
@ -426,7 +426,7 @@ The status posting endpoint takes an additional parameter, `in_reply_to_conversa
* Authentication: required
* Params:
* `file`: file needs to be uploaded with the multipart request or link to remote file.
* `shortcode`: (*optional*) shortcode for new emoji, must be uniq for all emoji. If not sended, shortcode will be taken from original filename.
* `shortcode`: (*optional*) shortcode for new emoji, must be unique for all emoji. If not sended, shortcode will be taken from original filename.
* `filename`: (*optional*) new emoji file name. If not specified will be taken from original filename.
* Response: JSON, list of files for updated pack (hashmap -> shortcode => filename) with status 200, either error status with error message.

View File

@ -249,6 +249,40 @@ This section describe PWA manifest instance-specific values. Currently this opti
* `base_url`: The base URL to access a user-uploaded file. Useful when you want to proxy the media files via another host/CDN fronts.
* `proxy_opts`: All options defined in `Pleroma.ReverseProxy` documentation, defaults to `[max_body_length: (25*1_048_576)]`.
* `whitelist`: List of domains to bypass the mediaproxy
* `invalidation`: options for remove media from cache after delete object:
* `enabled`: Enables purge cache
* `provider`: Which one of the [purge cache strategy](#purge-cache-strategy) to use.
### Purge cache strategy
#### Pleroma.Web.MediaProxy.Invalidation.Script
This strategy allow perform external bash script to purge cache.
Urls of attachments pass to script as arguments.
* `script_path`: path to external script.
Example:
```elixir
config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Script,
script_path: "./installation/nginx-cache-purge.example"
```
#### Pleroma.Web.MediaProxy.Invalidation.Http
This strategy allow perform custom http request to purge cache.
* `method`: http method. default is `purge`
* `headers`: http headers. default is empty
* `options`: request options. default is empty
Example:
```elixir
config :pleroma, Pleroma.Web.MediaProxy.Invalidation.Http,
method: :purge,
headers: [],
options: []
```
## Link previews
@ -619,24 +653,6 @@ config :pleroma, :workers,
* `enabled: false` corresponds to `config :pleroma, :workers, retries: [federator_outgoing: 1]`
* deprecated options: `max_jobs`, `initial_timeout`
### Pleroma.Scheduler
Configuration for [Quantum](https://github.com/quantum-elixir/quantum-core) jobs scheduler.
See [Quantum readme](https://github.com/quantum-elixir/quantum-core#usage) for the list of supported options.
Example:
```elixir
config :pleroma, Pleroma.Scheduler,
global: true,
overlap: true,
timezone: :utc,
jobs: [{"0 */6 * * * *", {Pleroma.Web.Websub, :refresh_subscriptions, []}}]
```
The above example defines a single job which invokes `Pleroma.Web.Websub.refresh_subscriptions()` every 6 hours ("0 */6 * * * *", [crontab format](https://en.wikipedia.org/wiki/Cron)).
## :web_push_encryption, :vapid_details
Web Push Notifications configuration. You can use the mix task `mix web_push.gen.keypair` to generate it.

View File

@ -0,0 +1,40 @@
#!/bin/sh
# A simple shell script to delete a media from the Nginx cache.
SCRIPTNAME=${0##*/}
# NGINX cache directory
CACHE_DIRECTORY="/tmp/pleroma-media-cache"
## Return the files where the items are cached.
## $1 - the filename, can be a pattern .
## $2 - the cache directory.
## $3 - (optional) the number of parallel processes to run for grep.
get_cache_files() {
local max_parallel=${3-16}
find $2 -maxdepth 2 -type d | xargs -P $max_parallel -n 1 grep -E Rl "^KEY:.*$1" | sort -u
}
## Removes an item from the given cache zone.
## $1 - the filename, can be a pattern .
## $2 - the cache directory.
purge_item() {
for f in $(get_cache_files $1 $2); do
echo "found file: $f"
[ -f $f ] || continue
echo "Deleting $f from $2."
rm $f
done
} # purge_item
purge() {
for url in "$@"
do
echo "$SCRIPTNAME delete \`$url\` from cache ($CACHE_DIRECTORY)"
purge_item $url $CACHE_DIRECTORY
done
}
purge $1

View File

@ -16,162 +16,78 @@ defmodule Pleroma.Emoji.Pack do
alias Pleroma.Emoji
@spec emoji_path() :: Path.t()
def emoji_path do
static = Pleroma.Config.get!([:instance, :static_dir])
Path.join(static, "emoji")
end
@spec create(String.t()) :: :ok | {:error, File.posix()} | {:error, :empty_values}
def create(name) when byte_size(name) > 0 do
dir = Path.join(emoji_path(), name)
with :ok <- File.mkdir(dir) do
%__MODULE__{
pack_file: Path.join(dir, "pack.json")
}
def create(name) do
with :ok <- validate_not_empty([name]),
dir <- Path.join(emoji_path(), name),
:ok <- File.mkdir(dir) do
%__MODULE__{pack_file: Path.join(dir, "pack.json")}
|> save_pack()
end
end
def create(_), do: {:error, :empty_values}
@spec show(String.t()) :: {:ok, t()} | {:loaded, nil} | {:error, :empty_values}
def show(name) when byte_size(name) > 0 do
with {_, %__MODULE__{} = pack} <- {:loaded, load_pack(name)},
{_, pack} <- validate_pack(pack) do
{:ok, pack}
@spec show(String.t()) :: {:ok, t()} | {:error, atom()}
def show(name) do
with :ok <- validate_not_empty([name]),
{:ok, pack} <- load_pack(name) do
{:ok, validate_pack(pack)}
end
end
def show(_), do: {:error, :empty_values}
@spec delete(String.t()) ::
{:ok, [binary()]} | {:error, File.posix(), binary()} | {:error, :empty_values}
def delete(name) when byte_size(name) > 0 do
emoji_path()
|> Path.join(name)
|> File.rm_rf()
end
def delete(_), do: {:error, :empty_values}
@spec add_file(String.t(), String.t(), Path.t(), Plug.Upload.t() | String.t()) ::
{:ok, t()} | {:error, File.posix()} | {:error, :empty_values}
def add_file(name, shortcode, filename, file)
when byte_size(name) > 0 and byte_size(shortcode) > 0 and byte_size(filename) > 0 do
with {_, nil} <- {:exists, Emoji.get(shortcode)},
{_, %__MODULE__{} = pack} <- {:loaded, load_pack(name)} do
file_path = Path.join(pack.path, filename)
create_subdirs(file_path)
case file do
%Plug.Upload{path: upload_path} ->
# Copy the uploaded file from the temporary directory
File.copy!(upload_path, file_path)
url when is_binary(url) ->
# Download and write the file
file_contents = Tesla.get!(url).body
File.write!(file_path, file_contents)
end
files = Map.put(pack.files, shortcode, filename)
updated_pack = %{pack | files: files}
case save_pack(updated_pack) do
:ok ->
Emoji.reload()
{:ok, updated_pack}
e ->
e
end
def delete(name) do
with :ok <- validate_not_empty([name]) do
emoji_path()
|> Path.join(name)
|> File.rm_rf()
end
end
def add_file(_, _, _, _), do: {:error, :empty_values}
defp create_subdirs(file_path) do
if String.contains?(file_path, "/") do
file_path
|> Path.dirname()
|> File.mkdir_p!()
@spec add_file(String.t(), String.t(), Path.t(), Plug.Upload.t() | String.t()) ::
{:ok, t()} | {:error, File.posix() | atom()}
def add_file(name, shortcode, filename, file) do
with :ok <- validate_not_empty([name, shortcode, filename]),
:ok <- validate_emoji_not_exists(shortcode),
{:ok, pack} <- load_pack(name),
:ok <- save_file(file, pack, filename),
{:ok, updated_pack} <- pack |> put_emoji(shortcode, filename) |> save_pack() do
Emoji.reload()
{:ok, updated_pack}
end
end
@spec delete_file(String.t(), String.t()) ::
{:ok, t()} | {:error, File.posix()} | {:error, :empty_values}
def delete_file(name, shortcode) when byte_size(name) > 0 and byte_size(shortcode) > 0 do
with {_, %__MODULE__{} = pack} <- {:loaded, load_pack(name)},
{_, {filename, files}} when not is_nil(filename) <-
{:exists, Map.pop(pack.files, shortcode)},
emoji <- Path.join(pack.path, filename),
{_, true} <- {:exists, File.exists?(emoji)} do
emoji_dir = Path.dirname(emoji)
File.rm!(emoji)
if String.contains?(filename, "/") and File.ls!(emoji_dir) == [] do
File.rmdir!(emoji_dir)
end
updated_pack = %{pack | files: files}
case save_pack(updated_pack) do
:ok ->
Emoji.reload()
{:ok, updated_pack}
e ->
e
end
{:ok, t()} | {:error, File.posix() | atom()}
def delete_file(name, shortcode) do
with :ok <- validate_not_empty([name, shortcode]),
{:ok, pack} <- load_pack(name),
:ok <- remove_file(pack, shortcode),
{:ok, updated_pack} <- pack |> delete_emoji(shortcode) |> save_pack() do
Emoji.reload()
{:ok, updated_pack}
end
end
def delete_file(_, _), do: {:error, :empty_values}
@spec update_file(String.t(), String.t(), String.t(), String.t(), boolean()) ::
{:ok, t()} | {:error, File.posix()} | {:error, :empty_values}
def update_file(name, shortcode, new_shortcode, new_filename, force)
when byte_size(name) > 0 and byte_size(shortcode) > 0 and byte_size(new_shortcode) > 0 and
byte_size(new_filename) > 0 do
with {_, %__MODULE__{} = pack} <- {:loaded, load_pack(name)},
{_, {filename, files}} when not is_nil(filename) <-
{:exists, Map.pop(pack.files, shortcode)},
{_, true} <- {:not_used, force or is_nil(Emoji.get(new_shortcode))} do
old_path = Path.join(pack.path, filename)
old_dir = Path.dirname(old_path)
new_path = Path.join(pack.path, new_filename)
create_subdirs(new_path)
:ok = File.rename(old_path, new_path)
if String.contains?(filename, "/") and File.ls!(old_dir) == [] do
File.rmdir!(old_dir)
end
files = Map.put(files, new_shortcode, new_filename)
updated_pack = %{pack | files: files}
case save_pack(updated_pack) do
:ok ->
Emoji.reload()
{:ok, updated_pack}
e ->
e
end
{:ok, t()} | {:error, File.posix() | atom()}
def update_file(name, shortcode, new_shortcode, new_filename, force) do
with :ok <- validate_not_empty([name, shortcode, new_shortcode, new_filename]),
{:ok, pack} <- load_pack(name),
{:ok, filename} <- get_filename(pack, shortcode),
:ok <- validate_emoji_not_exists(new_shortcode, force),
:ok <- rename_file(pack, filename, new_filename),
{:ok, updated_pack} <-
pack
|> delete_emoji(shortcode)
|> put_emoji(new_shortcode, new_filename)
|> save_pack() do
Emoji.reload()
{:ok, updated_pack}
end
end
def update_file(_, _, _, _, _), do: {:error, :empty_values}
@spec import_from_filesystem() :: {:ok, [String.t()]} | {:error, atom()}
@spec import_from_filesystem() :: {:ok, [String.t()]} | {:error, File.posix() | atom()}
def import_from_filesystem do
emoji_path = emoji_path()
@ -184,7 +100,7 @@ defmodule Pleroma.Emoji.Pack do
File.dir?(path) and File.exists?(Path.join(path, "pack.json"))
end)
|> Enum.map(&write_pack_contents/1)
|> Enum.filter(& &1)
|> Enum.reject(&is_nil/1)
{:ok, names}
else
@ -193,6 +109,117 @@ defmodule Pleroma.Emoji.Pack do
end
end
@spec list_remote(String.t()) :: {:ok, map()} | {:error, atom()}
def list_remote(url) do
uri = url |> String.trim() |> URI.parse()
with :ok <- validate_shareable_packs_available(uri) do
uri
|> URI.merge("/api/pleroma/emoji/packs")
|> http_get()
end
end
@spec list_local() :: {:ok, map()}
def list_local do
with {:ok, results} <- list_packs_dir() do
packs =
results
|> Enum.map(fn name ->
case load_pack(name) do
{:ok, pack} -> pack
_ -> nil
end
end)
|> Enum.reject(&is_nil/1)
|> Map.new(fn pack -> {pack.name, validate_pack(pack)} end)
{:ok, packs}
end
end
@spec get_archive(String.t()) :: {:ok, binary()} | {:error, atom()}
def get_archive(name) do
with {:ok, pack} <- load_pack(name),
:ok <- validate_downloadable(pack) do
{:ok, fetch_archive(pack)}
end
end
@spec download(String.t(), String.t(), String.t()) :: :ok | {:error, atom()}
def download(name, url, as) do
uri = url |> String.trim() |> URI.parse()
with :ok <- validate_shareable_packs_available(uri),
{:ok, remote_pack} <- uri |> URI.merge("/api/pleroma/emoji/packs/#{name}") |> http_get(),
{:ok, %{sha: sha, url: url} = pack_info} <- fetch_pack_info(remote_pack, uri, name),
{:ok, archive} <- download_archive(url, sha),
pack <- copy_as(remote_pack, as || name),
{:ok, _} = unzip(archive, pack_info, remote_pack, pack) do
# Fallback can't contain a pack.json file, since that would cause the fallback-src-sha256
# in it to depend on itself
if pack_info[:fallback] do
save_pack(pack)
else
{:ok, pack}
end
end
end
@spec save_metadata(map(), t()) :: {:ok, t()} | {:error, File.posix()}
def save_metadata(metadata, %__MODULE__{} = pack) do
pack
|> Map.put(:pack, metadata)
|> save_pack()
end
@spec update_metadata(String.t(), map()) :: {:ok, t()} | {:error, File.posix()}
def update_metadata(name, data) do
with {:ok, pack} <- load_pack(name) do
if fallback_sha_changed?(pack, data) do
update_sha_and_save_metadata(pack, data)
else
save_metadata(data, pack)
end
end
end
@spec load_pack(String.t()) :: {:ok, t()} | {:error, :not_found}
def load_pack(name) do
pack_file = Path.join([emoji_path(), name, "pack.json"])
if File.exists?(pack_file) do
pack =
pack_file
|> File.read!()
|> from_json()
|> Map.put(:pack_file, pack_file)
|> Map.put(:path, Path.dirname(pack_file))
|> Map.put(:name, name)
{:ok, pack}
else
{:error, :not_found}
end
end
@spec emoji_path() :: Path.t()
defp emoji_path do
[:instance, :static_dir]
|> Pleroma.Config.get!()
|> Path.join("emoji")
end
defp validate_emoji_not_exists(shortcode, force \\ false)
defp validate_emoji_not_exists(_shortcode, true), do: :ok
defp validate_emoji_not_exists(shortcode, _) do
case Emoji.get(shortcode) do
nil -> :ok
_ -> {:error, :already_exists}
end
end
defp write_pack_contents(path) do
pack = %__MODULE__{
files: files_from_path(path),
@ -201,7 +228,7 @@ defmodule Pleroma.Emoji.Pack do
}
case save_pack(pack) do
:ok -> Path.basename(path)
{:ok, _pack} -> Path.basename(path)
_ -> nil
end
end
@ -216,7 +243,8 @@ defmodule Pleroma.Emoji.Pack do
# FIXME: Copy-pasted from Pleroma.Emoji/load_from_file_stream/2
# Create a map of shortcodes to filenames from emoji.txt
File.read!(txt_path)
txt_path
|> File.read!()
|> String.split("\n")
|> Enum.map(&String.trim/1)
|> Enum.map(fn line ->
@ -226,21 +254,18 @@ defmodule Pleroma.Emoji.Pack do
[name, file | _] ->
file_dir_name = Path.dirname(file)
file =
if String.ends_with?(path, file_dir_name) do
Path.basename(file)
else
file
end
{name, file}
if String.ends_with?(path, file_dir_name) do
{name, Path.basename(file)}
else
{name, file}
end
_ ->
nil
end
end)
|> Enum.filter(& &1)
|> Enum.into(%{})
|> Enum.reject(&is_nil/1)
|> Map.new()
else
# If there's no emoji.txt, assume all files
# that are of certain extensions from the config are emojis and import them all
@ -249,60 +274,20 @@ defmodule Pleroma.Emoji.Pack do
end
end
@spec list_remote(String.t()) :: {:ok, map()}
def list_remote(url) do
uri =
url
|> String.trim()
|> URI.parse()
with {_, true} <- {:shareable, shareable_packs_available?(uri)} do
packs =
uri
|> URI.merge("/api/pleroma/emoji/packs")
|> to_string()
|> Tesla.get!()
|> Map.get(:body)
|> Jason.decode!()
{:ok, packs}
end
end
@spec list_local() :: {:ok, map()}
def list_local do
emoji_path = emoji_path()
# Create the directory first if it does not exist. This is probably the first request made
# with the API so it should be sufficient
with {:create_dir, :ok} <- {:create_dir, File.mkdir_p(emoji_path)},
{:ls, {:ok, results}} <- {:ls, File.ls(emoji_path)} do
packs =
results
|> Enum.map(&load_pack/1)
|> Enum.filter(& &1)
|> Enum.map(&validate_pack/1)
|> Map.new()
{:ok, packs}
end
end
defp validate_pack(pack) do
if downloadable?(pack) do
archive = fetch_archive(pack)
archive_sha = :crypto.hash(:sha256, archive) |> Base.encode16()
info =
if downloadable?(pack) do
archive = fetch_archive(pack)
archive_sha = :crypto.hash(:sha256, archive) |> Base.encode16()
info =
pack.pack
|> Map.put("can-download", true)
|> Map.put("download-sha256", archive_sha)
else
Map.put(pack.pack, "can-download", false)
end
{pack.name, Map.put(pack, :pack, info)}
else
info = Map.put(pack.pack, "can-download", false)
{pack.name, Map.put(pack, :pack, info)}
end
Map.put(pack, :pack, info)
end
defp downloadable?(pack) do
@ -315,26 +300,6 @@ defmodule Pleroma.Emoji.Pack do
end)
end
@spec get_archive(String.t()) :: {:ok, binary()}
def get_archive(name) do
with {_, %__MODULE__{} = pack} <- {:exists?, load_pack(name)},
{_, true} <- {:can_download?, downloadable?(pack)} do
{:ok, fetch_archive(pack)}
end
end
defp fetch_archive(pack) do
hash = :crypto.hash(:md5, File.read!(pack.pack_file))
case Cachex.get!(:emoji_packs_cache, pack.name) do
%{hash: ^hash, pack_data: archive} ->
archive
_ ->
create_archive_and_cache(pack, hash)
end
end
defp create_archive_and_cache(pack, hash) do
files = ['pack.json' | Enum.map(pack.files, fn {_, file} -> to_charlist(file) end)]
@ -356,152 +321,221 @@ defmodule Pleroma.Emoji.Pack do
result
end
@spec download(String.t(), String.t(), String.t()) :: :ok
def download(name, url, as) do
uri =
url
|> String.trim()
|> URI.parse()
with {_, true} <- {:shareable, shareable_packs_available?(uri)} do
remote_pack =
uri
|> URI.merge("/api/pleroma/emoji/packs/#{name}")
|> to_string()
|> Tesla.get!()
|> Map.get(:body)
|> Jason.decode!()
result =
case remote_pack["pack"] do
%{"share-files" => true, "can-download" => true, "download-sha256" => sha} ->
{:ok,
%{
sha: sha,
url: URI.merge(uri, "/api/pleroma/emoji/packs/#{name}/archive") |> to_string()
}}
%{"fallback-src" => src, "fallback-src-sha256" => sha} when is_binary(src) ->
{:ok,
%{
sha: sha,
url: src,
fallback: true
}}
_ ->
{:error,
"The pack was not set as shared and there is no fallback src to download from"}
end
with {:ok, %{sha: sha, url: url} = pinfo} <- result,
%{body: archive} <- Tesla.get!(url),
{_, true} <- {:checksum, Base.decode16!(sha) == :crypto.hash(:sha256, archive)} do
local_name = as || name
path = Path.join(emoji_path(), local_name)
pack = %__MODULE__{
name: local_name,
path: path,
files: remote_pack["files"],
pack_file: Path.join(path, "pack.json")
}
File.mkdir_p!(pack.path)
files = Enum.map(remote_pack["files"], fn {_, path} -> to_charlist(path) end)
# Fallback cannot contain a pack.json file
files = if pinfo[:fallback], do: files, else: ['pack.json' | files]
{:ok, _} = :zip.unzip(archive, cwd: to_charlist(pack.path), file_list: files)
# Fallback can't contain a pack.json file, since that would cause the fallback-src-sha256
# in it to depend on itself
if pinfo[:fallback] do
save_pack(pack)
end
:ok
end
end
end
defp save_pack(pack), do: File.write(pack.pack_file, Jason.encode!(pack, pretty: true))
@spec save_metadata(map(), t()) :: {:ok, t()} | {:error, File.posix()}
def save_metadata(metadata, %__MODULE__{} = pack) do
pack = Map.put(pack, :pack, metadata)
with :ok <- save_pack(pack) do
defp save_pack(pack) do
with {:ok, json} <- Jason.encode(pack, pretty: true),
:ok <- File.write(pack.pack_file, json) do
{:ok, pack}
end
end
@spec update_metadata(String.t(), map()) :: {:ok, t()} | {:error, File.posix()}
def update_metadata(name, data) do
pack = load_pack(name)
fb_sha_changed? =
not is_nil(data["fallback-src"]) and data["fallback-src"] != pack.pack["fallback-src"]
with {_, true} <- {:update?, fb_sha_changed?},
{:ok, %{body: zip}} <- Tesla.get(data["fallback-src"]),
{:ok, f_list} <- :zip.unzip(zip, [:memory]),
{_, true} <- {:has_all_files?, has_all_files?(pack.files, f_list)} do
fallback_sha = :crypto.hash(:sha256, zip) |> Base.encode16()
data
|> Map.put("fallback-src-sha256", fallback_sha)
|> save_metadata(pack)
else
{:update?, _} -> save_metadata(data, pack)
e -> e
end
end
# Check if all files from the pack.json are in the archive
defp has_all_files?(files, f_list) do
Enum.all?(files, fn {_, from_manifest} ->
List.keyfind(f_list, to_charlist(from_manifest), 0)
end)
end
@spec load_pack(String.t()) :: t() | nil
def load_pack(name) do
pack_file = Path.join([emoji_path(), name, "pack.json"])
if File.exists?(pack_file) do
pack_file
|> File.read!()
|> from_json()
|> Map.put(:pack_file, pack_file)
|> Map.put(:path, Path.dirname(pack_file))
|> Map.put(:name, name)
end
end
defp from_json(json) do
map = Jason.decode!(json)
struct(__MODULE__, %{files: map["files"], pack: map["pack"]})
end
defp shareable_packs_available?(uri) do
uri
|> URI.merge("/.well-known/nodeinfo")
|> to_string()
|> Tesla.get!()
|> Map.get(:body)
|> Jason.decode!()
|> Map.get("links")
|> List.last()
|> Map.get("href")
# Get the actual nodeinfo address and fetch it
|> Tesla.get!()
|> Map.get(:body)
|> Jason.decode!()
|> get_in(["metadata", "features"])
|> Enum.member?("shareable_emoji_packs")
defp validate_shareable_packs_available(uri) do
with {:ok, %{"links" => links}} <- uri |> URI.merge("/.well-known/nodeinfo") |> http_get(),
# Get the actual nodeinfo address and fetch it
{:ok, %{"metadata" => %{"features" => features}}} <-
links |> List.last() |> Map.get("href") |> http_get() do
if Enum.member?(features, "shareable_emoji_packs") do
:ok
else
{:error, :not_shareable}
end
end
end
defp validate_not_empty(list) do
if Enum.all?(list, fn i -> is_binary(i) and i != "" end) do
:ok
else
{:error, :empty_values}
end
end
defp save_file(file, pack, filename) do
file_path = Path.join(pack.path, filename)
create_subdirs(file_path)
case file do
%Plug.Upload{path: upload_path} ->
# Copy the uploaded file from the temporary directory
with {:ok, _} <- File.copy(upload_path, file_path), do: :ok
url when is_binary(url) ->
# Download and write the file
file_contents = Tesla.get!(url).body
File.write(file_path, file_contents)
end
end
defp put_emoji(pack, shortcode, filename) do
files = Map.put(pack.files, shortcode, filename)
%{pack | files: files}
end
defp delete_emoji(pack, shortcode) do
files = Map.delete(pack.files, shortcode)
%{pack | files: files}
end
defp rename_file(pack, filename, new_filename) do
old_path = Path.join(pack.path, filename)
new_path = Path.join(pack.path, new_filename)
create_subdirs(new_path)
with :ok <- File.rename(old_path, new_path) do
remove_dir_if_empty(old_path, filename)
end
end
defp create_subdirs(file_path) do
if String.contains?(file_path, "/") do
file_path
|> Path.dirname()
|> File.mkdir_p!()
end
end
defp remove_file(pack, shortcode) do
with {:ok, filename} <- get_filename(pack, shortcode),
emoji <- Path.join(pack.path, filename),
:ok <- File.rm(emoji) do
remove_dir_if_empty(emoji, filename)
end
end
defp remove_dir_if_empty(emoji, filename) do
dir = Path.dirname(emoji)
if String.contains?(filename, "/") and File.ls!(dir) == [] do
File.rmdir!(dir)
else
:ok
end
end
defp get_filename(pack, shortcode) do
with %{^shortcode => filename} when is_binary(filename) <- pack.files,
true <- pack.path |> Path.join(filename) |> File.exists?() do
{:ok, filename}
else
_ -> {:error, :doesnt_exist}
end
end
defp http_get(%URI{} = url), do: url |> to_string() |> http_get()
defp http_get(url) do
with {:ok, %{body: body}} <- url |> Pleroma.HTTP.get() do
Jason.decode(body)
end
end
defp list_packs_dir do
emoji_path = emoji_path()
# Create the directory first if it does not exist. This is probably the first request made
# with the API so it should be sufficient
with {:create_dir, :ok} <- {:create_dir, File.mkdir_p(emoji_path)},
{:ls, {:ok, results}} <- {:ls, File.ls(emoji_path)} do
{:ok, results}
else
{:create_dir, {:error, e}} -> {:error, :create_dir, e}
{:ls, {:error, e}} -> {:error, :ls, e}
end
end
defp validate_downloadable(pack) do
if downloadable?(pack), do: :ok, else: {:error, :cant_download}
end
defp copy_as(remote_pack, local_name) do
path = Path.join(emoji_path(), local_name)
%__MODULE__{
name: local_name,
path: path,
files: remote_pack["files"],
pack_file: Path.join(path, "pack.json")
}
end
defp unzip(archive, pack_info, remote_pack, local_pack) do
with :ok <- File.mkdir_p!(local_pack.path) do
files = Enum.map(remote_pack["files"], fn {_, path} -> to_charlist(path) end)
# Fallback cannot contain a pack.json file
files = if pack_info[:fallback], do: files, else: ['pack.json' | files]
:zip.unzip(archive, cwd: to_charlist(local_pack.path), file_list: files)
end
end
defp fetch_pack_info(remote_pack, uri, name) do
case remote_pack["pack"] do
%{"share-files" => true, "can-download" => true, "download-sha256" => sha} ->
{:ok,
%{
sha: sha,
url: URI.merge(uri, "/api/pleroma/emoji/packs/#{name}/archive") |> to_string()
}}
%{"fallback-src" => src, "fallback-src-sha256" => sha} when is_binary(src) ->
{:ok,
%{
sha: sha,
url: src,
fallback: true
}}
_ ->
{:error, "The pack was not set as shared and there is no fallback src to download from"}
end
end
defp download_archive(url, sha) do
with {:ok, %{body: archive}} <- Tesla.get(url) do
if Base.decode16!(sha) == :crypto.hash(:sha256, archive) do
{:ok, archive}
else
{:error, :imvalid_checksum}
end
end
end
defp fetch_archive(pack) do
hash = :crypto.hash(:md5, File.read!(pack.pack_file))
case Cachex.get!(:emoji_packs_cache, pack.name) do
%{hash: ^hash, pack_data: archive} -> archive
_ -> create_archive_and_cache(pack, hash)
end
end
defp fallback_sha_changed?(pack, data) do
is_binary(data[:"fallback-src"]) and data[:"fallback-src"] != pack.pack["fallback-src"]
end
defp update_sha_and_save_metadata(pack, data) do
with {:ok, %{body: zip}} <- Tesla.get(data[:"fallback-src"]),
:ok <- validate_has_all_files(pack, zip) do
fallback_sha = :sha256 |> :crypto.hash(zip) |> Base.encode16()
data
|> Map.put("fallback-src-sha256", fallback_sha)
|> save_metadata(pack)
end
end
defp validate_has_all_files(pack, zip) do
with {:ok, f_list} <- :zip.unzip(zip, [:memory]) do
# Check if all files from the pack.json are in the archive
pack.files
|> Enum.all?(fn {_, from_manifest} ->
List.keyfind(f_list, to_charlist(from_manifest), 0)
end)
|> if(do: :ok, else: {:error, :incomplete})
end
end
end

View File

@ -9,11 +9,13 @@ defmodule Pleroma.Object do
import Ecto.Changeset
alias Pleroma.Activity
alias Pleroma.Config
alias Pleroma.Object
alias Pleroma.Object.Fetcher
alias Pleroma.ObjectTombstone
alias Pleroma.Repo
alias Pleroma.User
alias Pleroma.Workers.AttachmentsCleanupWorker
require Logger
@ -188,27 +190,37 @@ defmodule Pleroma.Object do
def delete(%Object{data: %{"id" => id}} = object) do
with {:ok, _obj} = swap_object_with_tombstone(object),
deleted_activity = Activity.delete_all_by_object_ap_id(id),
{:ok, true} <- Cachex.del(:object_cache, "object:#{id}"),
{:ok, _} <- Cachex.del(:web_resp_cache, URI.parse(id).path) do
with true <- Pleroma.Config.get([:instance, :cleanup_attachments]) do
{:ok, _} =
Pleroma.Workers.AttachmentsCleanupWorker.enqueue("cleanup_attachments", %{
"object" => object
})
end
{:ok, _} <- invalid_object_cache(object) do
cleanup_attachments(
Config.get([:instance, :cleanup_attachments]),
%{"object" => object}
)
{:ok, object, deleted_activity}
end
end
def prune(%Object{data: %{"id" => id}} = object) do
@spec cleanup_attachments(boolean(), %{required(:object) => map()}) ::
{:ok, Oban.Job.t() | nil}
def cleanup_attachments(true, %{"object" => _} = params) do
AttachmentsCleanupWorker.enqueue("cleanup_attachments", params)
end
def cleanup_attachments(_, _), do: {:ok, nil}
def prune(%Object{data: %{"id" => _id}} = object) do
with {:ok, object} <- Repo.delete(object),
{:ok, true} <- Cachex.del(:object_cache, "object:#{id}"),
{:ok, _} <- Cachex.del(:web_resp_cache, URI.parse(id).path) do
{:ok, _} <- invalid_object_cache(object) do
{:ok, object}
end
end
def invalid_object_cache(%Object{data: %{"id" => id}}) do
with {:ok, true} <- Cachex.del(:object_cache, "object:#{id}") do
Cachex.del(:web_resp_cache, URI.parse(id).path)
end
end
def set_cache(%Object{data: %{"id" => ap_id}} = object) do
Cachex.put(:object_cache, "object:#{ap_id}", object)
{:ok, object}

View File

@ -1204,7 +1204,9 @@ defmodule Pleroma.User do
def get_recipients_from_activity(%Activity{recipients: to, actor: actor}) do
to = [actor | to]
User.Query.build(%{recipients_from_activity: to, local: true, deactivated: false})
query = User.Query.build(%{recipients_from_activity: to, local: true, deactivated: false})
query
|> Repo.all()
end
@ -1430,6 +1432,25 @@ defmodule Pleroma.User do
BackgroundWorker.enqueue("delete_user", %{"user_id" => user.id})
end
defp delete_and_invalidate_cache(%User{} = user) do
invalidate_cache(user)
Repo.delete(user)
end
defp delete_or_deactivate(%User{local: false} = user), do: delete_and_invalidate_cache(user)
defp delete_or_deactivate(%User{local: true} = user) do
status = account_status(user)
if status == :confirmation_pending do
delete_and_invalidate_cache(user)
else
user
|> change(%{deactivated: true, email: nil})
|> update_and_set_cache()
end
end
def perform(:force_password_reset, user), do: force_password_reset(user)
@spec perform(atom(), User.t()) :: {:ok, User.t()}
@ -1451,14 +1472,7 @@ defmodule Pleroma.User do
delete_user_activities(user)
if user.local do
user
|> change(%{deactivated: true, email: nil})
|> update_and_set_cache()
else
invalidate_cache(user)
Repo.delete(user)
end
delete_or_deactivate(user)
end
def perform(:deactivate_async, user, status), do: deactivate(user, status)

View File

@ -167,20 +167,18 @@ defmodule Pleroma.User.Query do
end
defp compose_query({:recipients_from_activity, to}, query) do
query
|> join(:left, [u], r in FollowingRelationship,
as: :relationships,
on: r.follower_id == u.id
following_query =
from(u in User,
join: f in FollowingRelationship,
on: u.id == f.following_id,
where: f.state == ^:follow_accept,
where: u.follower_address in ^to,
select: f.follower_id
)
from(u in query,
where: u.ap_id in ^to or u.id in subquery(following_query)
)
|> join(:left, [relationships: r], f in User,
as: :following,
on: f.id == r.following_id
)
|> where(
[u, following: f, relationships: r],
u.ap_id in ^to or (f.follower_address in ^to and r.state == ^:follow_accept)
)
|> distinct(true)
end
defp compose_query({:order_by, key}, query) do

View File

@ -393,7 +393,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
format: :password
},
agreement: %Schema{
type: :boolean,
allOf: [BooleanLike],
description:
"Whether the user agrees to the local rules, terms, and policies. These should be presented to the user in order to allow them to consent before setting this parameter to TRUE."
},
@ -463,7 +463,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
type: :object,
properties: %{
bot: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "Whether the account has a bot flag."
},
@ -486,7 +486,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
format: :binary
},
locked: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "Whether manual approval of follow requests is required."
},
@ -510,37 +510,37 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
# Pleroma-specific fields
no_rich_text: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "html tags are stripped from all statuses requested from the API"
},
hide_followers: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "user's followers will be hidden"
},
hide_follows: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "user's follows will be hidden"
},
hide_followers_count: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "user's follower count will be hidden"
},
hide_follows_count: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "user's follow count will be hidden"
},
hide_favorites: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "user's favorites timeline will be hidden"
},
show_role: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "user's role (e.g admin, moderator) will be exposed to anyone in the
API"
@ -552,12 +552,12 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
description: "Opaque user settings to be saved on the backend."
},
skip_thread_containment: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "Skip filtering out broken threads"
},
allow_following_move: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "Allows automatically follow moved following accounts"
},
@ -568,7 +568,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
format: :binary
},
discoverable: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description:
"Discovery of this account in search results and other services is allowed."
@ -678,7 +678,7 @@ defmodule Pleroma.Web.ApiSpec.AccountOperation do
type: :object,
properties: %{
notifications: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "Mute notifications in addition to statuses? Defaults to true.",
default: true

View File

@ -6,6 +6,7 @@ defmodule Pleroma.Web.ApiSpec.FilterOperation do
alias OpenApiSpex.Operation
alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.Helpers
alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
def open_api_operation(action) do
operation = String.to_existing_atom("#{action}_operation")
@ -171,7 +172,7 @@ defmodule Pleroma.Web.ApiSpec.FilterOperation do
type: :object,
properties: %{
irreversible: %Schema{
type: :bolean,
allOf: [BooleanLike],
description:
"Should the server irreversibly drop matching entities from home and notifications?",
default: false
@ -199,13 +200,13 @@ defmodule Pleroma.Web.ApiSpec.FilterOperation do
"Array of enumerable strings `home`, `notifications`, `public`, `thread`. At least one context must be specified."
},
irreversible: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description:
"Should the server irreversibly drop matching entities from home and notifications?"
},
whole_word: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "Consider word boundaries?",
default: true

View File

@ -125,11 +125,17 @@ defmodule Pleroma.Web.ApiSpec.InstanceOperation do
},
avatar_upload_limit: %Schema{type: :integer, description: "The title of the website"},
background_upload_limit: %Schema{type: :integer, description: "The title of the website"},
banner_upload_limit: %Schema{type: :integer, description: "The title of the website"}
banner_upload_limit: %Schema{type: :integer, description: "The title of the website"},
background_image: %Schema{
type: :string,
format: :uri,
description: "The background image for the website"
}
},
example: %{
"avatar_upload_limit" => 2_000_000,
"background_upload_limit" => 4_000_000,
"background_image" => "/static/image.png",
"banner_upload_limit" => 4_000_000,
"description" => "A Pleroma instance, an alternative fediverse server",
"email" => "lain@lain.com",

View File

@ -0,0 +1,390 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ApiSpec.PleromaEmojiPackOperation do
alias OpenApiSpex.Operation
alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.Schemas.ApiError
import Pleroma.Web.ApiSpec.Helpers
def open_api_operation(action) do
operation = String.to_existing_atom("#{action}_operation")
apply(__MODULE__, operation, [])
end
def remote_operation do
%Operation{
tags: ["Emoji Packs"],
summary: "Make request to another instance for emoji packs list",
security: [%{"oAuth" => ["write"]}],
parameters: [url_param()],
operationId: "PleromaAPI.EmojiPackController.remote",
responses: %{
200 => emoji_packs_response(),
500 => Operation.response("Error", "application/json", ApiError)
}
}
end
def index_operation do
%Operation{
tags: ["Emoji Packs"],
summary: "Lists local custom emoji packs",
operationId: "PleromaAPI.EmojiPackController.index",
responses: %{
200 => emoji_packs_response()
}
}
end
def show_operation do
%Operation{
tags: ["Emoji Packs"],
summary: "Show emoji pack",
operationId: "PleromaAPI.EmojiPackController.show",
parameters: [name_param()],
responses: %{
200 => Operation.response("Emoji Pack", "application/json", emoji_pack()),
400 => Operation.response("Bad Request", "application/json", ApiError),
404 => Operation.response("Not Found", "application/json", ApiError)
}
}
end
def archive_operation do
%Operation{
tags: ["Emoji Packs"],
summary: "Requests a local pack archive from the instance",
operationId: "PleromaAPI.EmojiPackController.archive",
parameters: [name_param()],
responses: %{
200 =>
Operation.response("Archive file", "application/octet-stream", %Schema{
type: :string,
format: :binary
}),
403 => Operation.response("Forbidden", "application/json", ApiError),
404 => Operation.response("Not Found", "application/json", ApiError)
}
}
end
def download_operation do
%Operation{
tags: ["Emoji Packs"],
summary: "Download pack from another instance",
operationId: "PleromaAPI.EmojiPackController.download",
security: [%{"oAuth" => ["write"]}],
requestBody: request_body("Parameters", download_request(), required: true),
responses: %{
200 => ok_response(),
500 => Operation.response("Error", "application/json", ApiError)
}
}
end
defp download_request do
%Schema{
type: :object,
required: [:url, :name],
properties: %{
url: %Schema{
type: :string,
format: :uri,
description: "URL of the instance to download from"
},
name: %Schema{type: :string, format: :uri, description: "Pack Name"},
as: %Schema{type: :string, format: :uri, description: "Save as"}
}
}
end
def create_operation do
%Operation{
tags: ["Emoji Packs"],
summary: "Create an empty pack",
operationId: "PleromaAPI.EmojiPackController.create",
security: [%{"oAuth" => ["write"]}],
parameters: [name_param()],
responses: %{
200 => ok_response(),
400 => Operation.response("Not Found", "application/json", ApiError),
409 => Operation.response("Conflict", "application/json", ApiError),
500 => Operation.response("Error", "application/json", ApiError)
}
}
end
def delete_operation do
%Operation{
tags: ["Emoji Packs"],
summary: "Delete a custom emoji pack",
operationId: "PleromaAPI.EmojiPackController.delete",
security: [%{"oAuth" => ["write"]}],
parameters: [name_param()],
responses: %{
200 => ok_response(),
400 => Operation.response("Bad Request", "application/json", ApiError),
404 => Operation.response("Not Found", "application/json", ApiError)
}
}
end
def update_operation do
%Operation{
tags: ["Emoji Packs"],
summary: "Updates (replaces) pack metadata",
operationId: "PleromaAPI.EmojiPackController.update",
security: [%{"oAuth" => ["write"]}],
requestBody: request_body("Parameters", update_request(), required: true),
parameters: [name_param()],
responses: %{
200 => Operation.response("Metadata", "application/json", metadata()),
400 => Operation.response("Bad Request", "application/json", ApiError)
}
}
end
def add_file_operation do
%Operation{
tags: ["Emoji Packs"],
summary: "Add new file to the pack",
operationId: "PleromaAPI.EmojiPackController.add_file",
security: [%{"oAuth" => ["write"]}],
requestBody: request_body("Parameters", add_file_request(), required: true),
parameters: [name_param()],
responses: %{
200 => Operation.response("Files Object", "application/json", files_object()),
400 => Operation.response("Bad Request", "application/json", ApiError),
409 => Operation.response("Conflict", "application/json", ApiError)
}
}
end
defp add_file_request do
%Schema{
type: :object,
required: [:file],
properties: %{
file: %Schema{
description:
"File needs to be uploaded with the multipart request or link to remote file",
anyOf: [
%Schema{type: :string, format: :binary},
%Schema{type: :string, format: :uri}
]
},
shortcode: %Schema{
type: :string,
description:
"Shortcode for new emoji, must be unique for all emoji. If not sended, shortcode will be taken from original filename."
},
filename: %Schema{
type: :string,
description:
"New emoji file name. If not specified will be taken from original filename."
}
}
}
end
def update_file_operation do
%Operation{
tags: ["Emoji Packs"],
summary: "Add new file to the pack",
operationId: "PleromaAPI.EmojiPackController.update_file",
security: [%{"oAuth" => ["write"]}],
requestBody: request_body("Parameters", update_file_request(), required: true),
parameters: [name_param()],
responses: %{
200 => Operation.response("Files Object", "application/json", files_object()),
400 => Operation.response("Bad Request", "application/json", ApiError),
409 => Operation.response("Conflict", "application/json", ApiError)
}
}
end
defp update_file_request do
%Schema{
type: :object,
required: [:shortcode, :new_shortcode, :new_filename],
properties: %{
shortcode: %Schema{
type: :string,
description: "Emoji file shortcode"
},
new_shortcode: %Schema{
type: :string,
description: "New emoji file shortcode"
},
new_filename: %Schema{
type: :string,
description: "New filename for emoji file"
},
force: %Schema{
type: :boolean,
description: "With true value to overwrite existing emoji with new shortcode",
default: false
}
}
}
end
def delete_file_operation do
%Operation{
tags: ["Emoji Packs"],
summary: "Delete emoji file from pack",
operationId: "PleromaAPI.EmojiPackController.delete_file",
security: [%{"oAuth" => ["write"]}],
parameters: [
name_param(),
Operation.parameter(:shortcode, :query, :string, "File shortcode",
example: "cofe",
required: true
)
],
responses: %{
200 => Operation.response("Files Object", "application/json", files_object()),
400 => Operation.response("Bad Request", "application/json", ApiError)
}
}
end
def import_from_filesystem_operation do
%Operation{
tags: ["Emoji Packs"],
summary: "Imports packs from filesystem",
operationId: "PleromaAPI.EmojiPackController.import",
security: [%{"oAuth" => ["write"]}],
responses: %{
200 =>
Operation.response("Array of imported pack names", "application/json", %Schema{
type: :array,
items: %Schema{type: :string}
})
}
}
end
defp name_param do
Operation.parameter(:name, :path, :string, "Pack Name", example: "cofe", required: true)
end
defp url_param do
Operation.parameter(
:url,
:query,
%Schema{type: :string, format: :uri},
"URL of the instance",
required: true
)
end
defp ok_response do
Operation.response("Ok", "application/json", %Schema{type: :string, example: "ok"})
end
defp emoji_packs_response do
Operation.response(
"Object with pack names as keys and pack contents as values",
"application/json",
%Schema{
type: :object,
additionalProperties: emoji_pack(),
example: %{
"emojos" => emoji_pack().example
}
}
)
end
defp emoji_pack do
%Schema{
title: "EmojiPack",
type: :object,
properties: %{
files: files_object(),
pack: %Schema{
type: :object,
properties: %{
license: %Schema{type: :string},
homepage: %Schema{type: :string, format: :uri},
description: %Schema{type: :string},
"can-download": %Schema{type: :boolean},
"share-files": %Schema{type: :boolean},
"download-sha256": %Schema{type: :string}
}
}
},
example: %{
"files" => %{"emacs" => "emacs.png", "guix" => "guix.png"},
"pack" => %{
"license" => "Test license",
"homepage" => "https://pleroma.social",
"description" => "Test description",
"can-download" => true,
"share-files" => true,
"download-sha256" => "57482F30674FD3DE821FF48C81C00DA4D4AF1F300209253684ABA7075E5FC238"
}
}
}
end
defp files_object do
%Schema{
type: :object,
additionalProperties: %Schema{type: :string},
description: "Object with emoji names as keys and filenames as values"
}
end
defp update_request do
%Schema{
type: :object,
properties: %{
metadata: %Schema{
type: :object,
description: "Metadata to replace the old one",
properties: %{
license: %Schema{type: :string},
homepage: %Schema{type: :string, format: :uri},
description: %Schema{type: :string},
"fallback-src": %Schema{
type: :string,
format: :uri,
description: "Fallback url to download pack from"
},
"fallback-src-sha256": %Schema{
type: :string,
description: "SHA256 encoded for fallback pack archive"
},
"share-files": %Schema{type: :boolean, description: "Is pack allowed for sharing?"}
}
}
}
}
end
defp metadata do
%Schema{
type: :object,
properties: %{
license: %Schema{type: :string},
homepage: %Schema{type: :string, format: :uri},
description: %Schema{type: :string},
"fallback-src": %Schema{
type: :string,
format: :uri,
description: "Fallback url to download pack from"
},
"fallback-src-sha256": %Schema{
type: :string,
description: "SHA256 encoded for fallback pack archive"
},
"share-files": %Schema{type: :boolean, description: "Is pack allowed for sharing?"}
}
}
end
end

View File

@ -0,0 +1,79 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ApiSpec.PleromaMascotOperation do
alias OpenApiSpex.Operation
alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.Schemas.ApiError
import Pleroma.Web.ApiSpec.Helpers
def open_api_operation(action) do
operation = String.to_existing_atom("#{action}_operation")
apply(__MODULE__, operation, [])
end
def show_operation do
%Operation{
tags: ["Mascot"],
summary: "Gets user mascot image",
security: [%{"oAuth" => ["read:accounts"]}],
operationId: "PleromaAPI.MascotController.show",
responses: %{
200 => Operation.response("Mascot", "application/json", mascot())
}
}
end
def update_operation do
%Operation{
tags: ["Mascot"],
summary: "Set/clear user avatar image",
description:
"Behaves exactly the same as `POST /api/v1/upload`. Can only accept images - any attempt to upload non-image files will be met with `HTTP 415 Unsupported Media Type`.",
operationId: "PleromaAPI.MascotController.update",
requestBody:
request_body(
"Parameters",
%Schema{
type: :object,
properties: %{
file: %Schema{type: :string, format: :binary}
}
},
required: true
),
security: [%{"oAuth" => ["write:accounts"]}],
responses: %{
200 => Operation.response("Mascot", "application/json", mascot()),
415 => Operation.response("Unsupported Media Type", "application/json", ApiError)
}
}
end
defp mascot do
%Schema{
type: :object,
properties: %{
id: %Schema{type: :string},
url: %Schema{type: :string, format: :uri},
type: %Schema{type: :string},
pleroma: %Schema{
type: :object,
properties: %{
mime_type: %Schema{type: :string}
}
}
},
example: %{
"id" => "abcdefg",
"url" => "https://pleroma.example.org/media/abcdefg.png",
"type" => "image",
"pleroma" => %{
"mime_type" => "image/png"
}
}
}
end
end

View File

@ -0,0 +1,102 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.ApiSpec.PleromaScrobbleOperation do
alias OpenApiSpex.Operation
alias OpenApiSpex.Reference
alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.Schemas.Account
alias Pleroma.Web.ApiSpec.Schemas.VisibilityScope
import Pleroma.Web.ApiSpec.Helpers
def open_api_operation(action) do
operation = String.to_existing_atom("#{action}_operation")
apply(__MODULE__, operation, [])
end
def create_operation do
%Operation{
tags: ["Scrobbles"],
summary: "Creates a new Listen activity for an account",
security: [%{"oAuth" => ["write"]}],
operationId: "PleromaAPI.ScrobbleController.create",
requestBody: request_body("Parameters", create_request(), requried: true),
responses: %{
200 => Operation.response("Scrobble", "application/json", scrobble())
}
}
end
def index_operation do
%Operation{
tags: ["Scrobbles"],
summary: "Requests a list of current and recent Listen activities for an account",
operationId: "PleromaAPI.ScrobbleController.index",
parameters: [
%Reference{"$ref": "#/components/parameters/accountIdOrNickname"} | pagination_params()
],
security: [%{"oAuth" => ["read"]}],
responses: %{
200 =>
Operation.response("Array of Scrobble", "application/json", %Schema{
type: :array,
items: scrobble()
})
}
}
end
defp create_request do
%Schema{
type: :object,
required: [:title],
properties: %{
title: %Schema{type: :string, description: "The title of the media playing"},
album: %Schema{type: :string, description: "The album of the media playing"},
artist: %Schema{type: :string, description: "The artist of the media playing"},
length: %Schema{type: :integer, description: "The length of the media playing"},
visibility: %Schema{
allOf: [VisibilityScope],
default: "public",
description: "Scrobble visibility"
}
},
example: %{
"title" => "Some Title",
"artist" => "Some Artist",
"album" => "Some Album",
"length" => 180_000
}
}
end
defp scrobble do
%Schema{
type: :object,
properties: %{
id: %Schema{type: :string},
account: Account,
title: %Schema{type: :string, description: "The title of the media playing"},
album: %Schema{type: :string, description: "The album of the media playing"},
artist: %Schema{type: :string, description: "The artist of the media playing"},
length: %Schema{
type: :integer,
description: "The length of the media playing",
nullable: true
},
created_at: %Schema{type: :string, format: :"date-time"}
},
example: %{
"id" => "1234",
"account" => Account.schema().example,
"title" => "Some Title",
"artist" => "Some Artist",
"album" => "Some Album",
"length" => 180_000,
"created_at" => "2019-09-28T12:40:45.000Z"
}
}
end
end

View File

@ -7,6 +7,7 @@ defmodule Pleroma.Web.ApiSpec.ReportOperation do
alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.Helpers
alias Pleroma.Web.ApiSpec.Schemas.ApiError
alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
def open_api_operation(action) do
operation = String.to_existing_atom("#{action}_operation")
@ -47,7 +48,7 @@ defmodule Pleroma.Web.ApiSpec.ReportOperation do
description: "Reason for the report"
},
forward: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
default: false,
description:

View File

@ -7,6 +7,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.AccountOperation
alias Pleroma.Web.ApiSpec.Schemas.ApiError
alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
alias Pleroma.Web.ApiSpec.Schemas.FlakeID
alias Pleroma.Web.ApiSpec.Schemas.ScheduledStatus
alias Pleroma.Web.ApiSpec.Schemas.Status
@ -394,12 +395,12 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
"Duration the poll should be open, in seconds. Must be provided with `poll[options]`"
},
multiple: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "Allow multiple choices?"
},
hide_totals: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "Hide vote counts until the poll ends?"
}
@ -411,7 +412,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
description: "ID of the status being replied to, if status is a reply"
},
sensitive: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "Mark status and attached media as sensitive?"
},
@ -435,7 +436,7 @@ defmodule Pleroma.Web.ApiSpec.StatusOperation do
},
# Pleroma-specific properties:
preview: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description:
"If set to `true` the post won't be actually posted, but the status entitiy would still be rendered back. This could be useful for previewing rich text/custom emoji, for example"

View File

@ -7,6 +7,7 @@ defmodule Pleroma.Web.ApiSpec.SubscriptionOperation do
alias OpenApiSpex.Schema
alias Pleroma.Web.ApiSpec.Helpers
alias Pleroma.Web.ApiSpec.Schemas.ApiError
alias Pleroma.Web.ApiSpec.Schemas.BooleanLike
alias Pleroma.Web.ApiSpec.Schemas.PushSubscription
def open_api_operation(action) do
@ -117,27 +118,27 @@ defmodule Pleroma.Web.ApiSpec.SubscriptionOperation do
type: :object,
properties: %{
follow: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "Receive follow notifications?"
},
favourite: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "Receive favourite notifications?"
},
reblog: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "Receive reblog notifications?"
},
mention: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "Receive mention notifications?"
},
poll: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "Receive poll notifications?"
}
@ -181,27 +182,27 @@ defmodule Pleroma.Web.ApiSpec.SubscriptionOperation do
type: :object,
properties: %{
follow: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "Receive follow notifications?"
},
favourite: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "Receive favourite notifications?"
},
reblog: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "Receive reblog notifications?"
},
mention: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "Receive mention notifications?"
},
poll: %Schema{
type: :boolean,
allOf: [BooleanLike],
nullable: true,
description: "Receive poll notifications?"
}

View File

@ -387,11 +387,14 @@ defmodule Pleroma.Web.CommonAPI do
|> check_expiry_date()
end
def listen(user, %{"title" => _} = data) do
with visibility <- data["visibility"] || "public",
{to, cc} <- get_to_and_cc(user, [], nil, visibility, nil),
def listen(user, data) do
visibility = Map.get(data, :visibility, "public")
with {to, cc} <- get_to_and_cc(user, [], nil, visibility, nil),
listen_data <-
Map.take(data, ["album", "artist", "title", "length"])
data
|> Map.take([:album, :artist, :title, :length])
|> Map.new(fn {key, value} -> {to_string(key), value} end)
|> Map.put("type", "Audio")
|> Map.put("to", to)
|> Map.put("cc", cc)

View File

@ -177,6 +177,7 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
)
|> add_if_present(params, :pleroma_settings_store, :pleroma_settings_store)
|> add_if_present(params, :default_scope, :default_scope)
|> add_if_present(params["source"], "privacy", :default_scope)
|> add_if_present(params, :actor_type, :actor_type)
changeset = User.update_changeset(user, user_params)
@ -189,7 +190,8 @@ defmodule Pleroma.Web.MastodonAPI.AccountController do
end
defp add_if_present(map, params, params_field, map_field, value_function \\ &{:ok, &1}) do
with true <- Map.has_key?(params, params_field),
with true <- is_map(params),
true <- Map.has_key?(params, params_field),
{:ok, new_value} <- value_function.(Map.get(params, params_field)) do
Map.put(map, map_field, new_value)
else

View File

@ -33,6 +33,7 @@ defmodule Pleroma.Web.MastodonAPI.InstanceView do
avatar_upload_limit: Keyword.get(instance, :avatar_upload_limit),
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),
pleroma: %{
metadata: %{
features: features(),

View File

@ -436,27 +436,6 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do
}
end
def render("listen.json", %{activity: %Activity{data: %{"type" => "Listen"}} = activity} = opts) do
object = Object.normalize(activity)
user = get_user(activity.data["actor"])
created_at = Utils.to_masto_date(activity.data["published"])
%{
id: activity.id,
account: AccountView.render("show.json", %{user: user, for: opts[:for]}),
created_at: created_at,
title: object.data["title"] |> HTML.strip_tags(),
artist: object.data["artist"] |> HTML.strip_tags(),
album: object.data["album"] |> HTML.strip_tags(),
length: object.data["length"]
}
end
def render("listens.json", opts) do
safe_render_many(opts.activities, StatusView, "listen.json", opts)
end
def render("context.json", %{activity: activity, activities: activities, user: user}) do
%{ancestors: ancestors, descendants: descendants} =
activities

View File

@ -0,0 +1,26 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MediaProxy.Invalidation do
@moduledoc false
@callback purge(list(String.t()), map()) :: {:ok, String.t()} | {:error, String.t()}
alias Pleroma.Config
@spec purge(list(String.t())) :: {:ok, String.t()} | {:error, String.t()}
def purge(urls) do
[:media_proxy, :invalidation, :enabled]
|> Config.get()
|> do_purge(urls)
end
defp do_purge(true, urls) do
provider = Config.get([:media_proxy, :invalidation, :provider])
options = Config.get(provider)
provider.purge(urls, options)
end
defp do_purge(_, _), do: :ok
end

View File

@ -0,0 +1,40 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MediaProxy.Invalidation.Http do
@moduledoc false
@behaviour Pleroma.Web.MediaProxy.Invalidation
require Logger
@impl Pleroma.Web.MediaProxy.Invalidation
def purge(urls, opts) do
method = Map.get(opts, :method, :purge)
headers = Map.get(opts, :headers, [])
options = Map.get(opts, :options, [])
Logger.debug("Running cache purge: #{inspect(urls)}")
Enum.each(urls, fn url ->
with {:error, error} <- do_purge(method, url, headers, options) do
Logger.error("Error while cache purge: url - #{url}, error: #{inspect(error)}")
end
end)
{:ok, "success"}
end
defp do_purge(method, url, headers, options) do
case Pleroma.HTTP.request(method, url, "", headers, options) do
{:ok, %{status: status} = env} when 400 <= status and status < 500 ->
{:error, env}
{:error, error} = error ->
error
_ ->
{:ok, "success"}
end
end
end

View File

@ -0,0 +1,41 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.MediaProxy.Invalidation.Script do
@moduledoc false
@behaviour Pleroma.Web.MediaProxy.Invalidation
require Logger
@impl Pleroma.Web.MediaProxy.Invalidation
def purge(urls, %{script_path: script_path} = _options) do
args =
urls
|> List.wrap()
|> Enum.uniq()
|> Enum.join(" ")
path = Path.expand(script_path)
Logger.debug("Running cache purge: #{inspect(urls)}, #{path}")
case do_purge(path, [args]) do
{result, exit_status} when exit_status > 0 ->
Logger.error("Error while cache purge: #{inspect(result)}")
{:error, inspect(result)}
_ ->
{:ok, "success"}
end
end
def purge(_, _), do: {:error, "not found script path"}
defp do_purge(path, args) do
System.cmd(path, args)
rescue
error -> {inspect(error), 1}
end
end

View File

@ -1,8 +1,10 @@
defmodule Pleroma.Web.PleromaAPI.EmojiAPIController do
defmodule Pleroma.Web.PleromaAPI.EmojiPackController do
use Pleroma.Web, :controller
alias Pleroma.Emoji.Pack
plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(
Pleroma.Plugs.OAuthScopesPlug,
%{scopes: ["write"], admin: true}
@ -19,39 +21,37 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIController do
]
)
plug(
:skip_plug,
[Pleroma.Plugs.OAuthScopesPlug, Pleroma.Plugs.ExpectPublicOrAuthenticatedCheckPlug]
when action in [:archive, :show, :list]
)
@skip_plugs [Pleroma.Plugs.OAuthScopesPlug, Pleroma.Plugs.ExpectPublicOrAuthenticatedCheckPlug]
plug(:skip_plug, @skip_plugs when action in [:archive, :show, :list])
def remote(conn, %{"url" => url}) do
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaEmojiPackOperation
def remote(conn, %{url: url}) do
with {:ok, packs} <- Pack.list_remote(url) do
json(conn, packs)
else
{:shareable, _} ->
{:error, :not_shareable} ->
conn
|> put_status(:internal_server_error)
|> json(%{error: "The requested instance does not support sharing emoji packs"})
end
end
def list(conn, _params) do
def index(conn, _params) do
emoji_path =
Path.join(
Pleroma.Config.get!([:instance, :static_dir]),
"emoji"
)
[:instance, :static_dir]
|> Pleroma.Config.get!()
|> Path.join("emoji")
with {:ok, packs} <- Pack.list_local() do
json(conn, packs)
else
{:create_dir, {:error, e}} ->
{:error, :create_dir, e} ->
conn
|> put_status(:internal_server_error)
|> json(%{error: "Failed to create the emoji pack directory at #{emoji_path}: #{e}"})
{:ls, {:error, e}} ->
{:error, :ls, e} ->
conn
|> put_status(:internal_server_error)
|> json(%{
@ -60,13 +60,13 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIController do
end
end
def show(conn, %{"name" => name}) do
def show(conn, %{name: name}) do
name = String.trim(name)
with {:ok, pack} <- Pack.show(name) do
json(conn, pack)
else
{:loaded, _} ->
{:error, :not_found} ->
conn
|> put_status(:not_found)
|> json(%{error: "Pack #{name} does not exist"})
@ -78,11 +78,11 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIController do
end
end
def archive(conn, %{"name" => name}) do
def archive(conn, %{name: name}) do
with {:ok, archive} <- Pack.get_archive(name) do
send_download(conn, {:binary, archive}, filename: "#{name}.zip")
else
{:can_download?, _} ->
{:error, :cant_download} ->
conn
|> put_status(:forbidden)
|> json(%{
@ -90,23 +90,23 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIController do
"Pack #{name} cannot be downloaded from this instance, either pack sharing was disabled for this pack or some files are missing"
})
{:exists?, _} ->
{:error, :not_found} ->
conn
|> put_status(:not_found)
|> json(%{error: "Pack #{name} does not exist"})
end
end
def download(conn, %{"url" => url, "name" => name} = params) do
with :ok <- Pack.download(name, url, params["as"]) do
def download(%{body_params: %{url: url, name: name} = params} = conn, _) do
with {:ok, _pack} <- Pack.download(name, url, params[:as]) do
json(conn, "ok")
else
{:shareable, _} ->
{:error, :not_shareable} ->
conn
|> put_status(:internal_server_error)
|> json(%{error: "The requested instance does not support sharing emoji packs"})
{:checksum, _} ->
{:error, :imvalid_checksum} ->
conn
|> put_status(:internal_server_error)
|> json(%{error: "SHA256 for the pack doesn't match the one sent by the server"})
@ -118,10 +118,10 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIController do
end
end
def create(conn, %{"name" => name}) do
def create(conn, %{name: name}) do
name = String.trim(name)
with :ok <- Pack.create(name) do
with {:ok, _pack} <- Pack.create(name) do
json(conn, "ok")
else
{:error, :eexist} ->
@ -143,7 +143,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIController do
end
end
def delete(conn, %{"name" => name}) do
def delete(conn, %{name: name}) do
name = String.trim(name)
with {:ok, deleted} when deleted != [] <- Pack.delete(name) do
@ -166,11 +166,11 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIController do
end
end
def update(conn, %{"name" => name, "metadata" => metadata}) do
def update(%{body_params: %{metadata: metadata}} = conn, %{name: name}) do
with {:ok, pack} <- Pack.update_metadata(name, metadata) do
json(conn, pack.pack)
else
{:has_all_files?, _} ->
{:error, :incomplete} ->
conn
|> put_status(:bad_request)
|> json(%{error: "The fallback archive does not have all files specified in pack.json"})
@ -184,19 +184,19 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIController do
end
end
def add_file(conn, %{"name" => name} = params) do
filename = params["filename"] || get_filename(params["file"])
shortcode = params["shortcode"] || Path.basename(filename, Path.extname(filename))
def add_file(%{body_params: params} = conn, %{name: name}) do
filename = params[:filename] || get_filename(params[:file])
shortcode = params[:shortcode] || Path.basename(filename, Path.extname(filename))
with {:ok, pack} <- Pack.add_file(name, shortcode, filename, params["file"]) do
with {:ok, pack} <- Pack.add_file(name, shortcode, filename, params[:file]) do
json(conn, pack.files)
else
{:exists, _} ->
{:error, :already_exists} ->
conn
|> put_status(:conflict)
|> json(%{error: "An emoji with the \"#{shortcode}\" shortcode already exists"})
{:loaded, _} ->
{:error, :not_found} ->
conn
|> put_status(:bad_request)
|> json(%{error: "pack \"#{name}\" is not found"})
@ -215,20 +215,20 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIController do
end
end
def update_file(conn, %{"name" => name, "shortcode" => shortcode} = params) do
new_shortcode = params["new_shortcode"]
new_filename = params["new_filename"]
force = params["force"] == true
def update_file(%{body_params: %{shortcode: shortcode} = params} = conn, %{name: name}) do
new_shortcode = params[:new_shortcode]
new_filename = params[:new_filename]
force = params[:force]
with {:ok, pack} <- Pack.update_file(name, shortcode, new_shortcode, new_filename, force) do
json(conn, pack.files)
else
{:exists, _} ->
{:error, :doesnt_exist} ->
conn
|> put_status(:bad_request)
|> json(%{error: "Emoji \"#{shortcode}\" does not exist"})
{:not_used, _} ->
{:error, :already_exists} ->
conn
|> put_status(:conflict)
|> json(%{
@ -236,7 +236,7 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIController do
"New shortcode \"#{new_shortcode}\" is already used. If you want to override emoji use 'force' option"
})
{:loaded, _} ->
{:error, :not_found} ->
conn
|> put_status(:bad_request)
|> json(%{error: "pack \"#{name}\" is not found"})
@ -255,16 +255,16 @@ defmodule Pleroma.Web.PleromaAPI.EmojiAPIController do
end
end
def delete_file(conn, %{"name" => name, "shortcode" => shortcode}) do
def delete_file(conn, %{name: name, shortcode: shortcode}) do
with {:ok, pack} <- Pack.delete_file(name, shortcode) do
json(conn, pack.files)
else
{:exists, _} ->
{:error, :doesnt_exist} ->
conn
|> put_status(:bad_request)
|> json(%{error: "Emoji \"#{shortcode}\" does not exist"})
{:loaded, _} ->
{:error, :not_found} ->
conn
|> put_status(:bad_request)
|> json(%{error: "pack \"#{name}\" is not found"})

View File

@ -9,16 +9,19 @@ defmodule Pleroma.Web.PleromaAPI.MascotController do
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(OAuthScopesPlug, %{scopes: ["read:accounts"]} when action == :show)
plug(OAuthScopesPlug, %{scopes: ["write:accounts"]} when action != :show)
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaMascotOperation
@doc "GET /api/v1/pleroma/mascot"
def show(%{assigns: %{user: user}} = conn, _params) do
json(conn, User.get_mascot(user))
end
@doc "PUT /api/v1/pleroma/mascot"
def update(%{assigns: %{user: user}} = conn, %{"file" => file}) do
def update(%{assigns: %{user: user}, body_params: %{file: file}} = conn, _) do
with {:ok, object} <- ActivityPub.upload(file, actor: User.ap_id(user)),
# Reject if not an image
%{type: "image"} = attachment <- render_attachment(object) do

View File

@ -5,34 +5,27 @@
defmodule Pleroma.Web.PleromaAPI.ScrobbleController do
use Pleroma.Web, :controller
import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2, fetch_integer_param: 2]
import Pleroma.Web.ControllerHelper, only: [add_link_headers: 2]
alias Pleroma.Plugs.OAuthScopesPlug
alias Pleroma.User
alias Pleroma.Web.ActivityPub.ActivityPub
alias Pleroma.Web.CommonAPI
alias Pleroma.Web.MastodonAPI.StatusView
plug(Pleroma.Web.ApiSpec.CastAndValidate)
plug(
OAuthScopesPlug,
%{scopes: ["read"], fallback: :proceed_unauthenticated} when action == :user_scrobbles
%{scopes: ["read"], fallback: :proceed_unauthenticated} when action == :index
)
plug(OAuthScopesPlug, %{scopes: ["write"]} when action != :user_scrobbles)
plug(OAuthScopesPlug, %{scopes: ["write"]} when action == :create)
def new_scrobble(%{assigns: %{user: user}} = conn, %{"title" => _} = params) do
params =
if !params["length"] do
params
else
params
|> Map.put("length", fetch_integer_param(params, "length"))
end
defdelegate open_api_operation(action), to: Pleroma.Web.ApiSpec.PleromaScrobbleOperation
def create(%{assigns: %{user: user}, body_params: params} = conn, _) do
with {:ok, activity} <- CommonAPI.listen(user, params) do
conn
|> put_view(StatusView)
|> render("listen.json", %{activity: activity, for: user})
render(conn, "show.json", activity: activity, for: user)
else
{:error, message} ->
conn
@ -41,16 +34,18 @@ defmodule Pleroma.Web.PleromaAPI.ScrobbleController do
end
end
def user_scrobbles(%{assigns: %{user: reading_user}} = conn, params) do
with %User{} = user <- User.get_cached_by_nickname_or_id(params["id"], for: reading_user) do
params = Map.put(params, "type", ["Listen"])
def index(%{assigns: %{user: reading_user}} = conn, %{id: id} = params) do
with %User{} = user <- User.get_cached_by_nickname_or_id(id, for: reading_user) do
params =
params
|> Map.new(fn {key, value} -> {to_string(key), value} end)
|> Map.put("type", ["Listen"])
activities = ActivityPub.fetch_user_abstract_activities(user, reading_user, params)
conn
|> add_link_headers(activities)
|> put_view(StatusView)
|> render("listens.json", %{
|> render("index.json", %{
activities: activities,
for: reading_user,
as: :activity

View File

@ -0,0 +1,37 @@
# Pleroma: A lightweight social networking server
# Copyright © 2017-2020 Pleroma Authors <https://pleroma.social/>
# SPDX-License-Identifier: AGPL-3.0-only
defmodule Pleroma.Web.PleromaAPI.ScrobbleView do
use Pleroma.Web, :view
require Pleroma.Constants
alias Pleroma.Activity
alias Pleroma.HTML
alias Pleroma.Object
alias Pleroma.Web.CommonAPI.Utils
alias Pleroma.Web.MastodonAPI.AccountView
alias Pleroma.Web.MastodonAPI.StatusView
def render("show.json", %{activity: %Activity{data: %{"type" => "Listen"}} = activity} = opts) do
object = Object.normalize(activity)
user = StatusView.get_user(activity.data["actor"])
created_at = Utils.to_masto_date(activity.data["published"])
%{
id: activity.id,
account: AccountView.render("show.json", %{user: user, for: opts[:for]}),
created_at: created_at,
title: object.data["title"] |> HTML.strip_tags(),
artist: object.data["artist"] |> HTML.strip_tags(),
album: object.data["album"] |> HTML.strip_tags(),
length: object.data["length"]
}
end
def render("index.json", opts) do
safe_render_many(opts.activities, __MODULE__, "show.json", opts)
end
end

View File

@ -216,24 +216,25 @@ defmodule Pleroma.Web.Router do
scope "/packs" do
pipe_through(:admin_api)
get("/import", EmojiAPIController, :import_from_filesystem)
get("/remote", EmojiAPIController, :remote)
post("/download", EmojiAPIController, :download)
get("/import", EmojiPackController, :import_from_filesystem)
get("/remote", EmojiPackController, :remote)
post("/download", EmojiPackController, :download)
post("/:name", EmojiAPIController, :create)
patch("/:name", EmojiAPIController, :update)
delete("/:name", EmojiAPIController, :delete)
post("/:name", EmojiPackController, :create)
patch("/:name", EmojiPackController, :update)
delete("/:name", EmojiPackController, :delete)
post("/:name/files", EmojiAPIController, :add_file)
patch("/:name/files", EmojiAPIController, :update_file)
delete("/:name/files", EmojiAPIController, :delete_file)
post("/:name/files", EmojiPackController, :add_file)
patch("/:name/files", EmojiPackController, :update_file)
delete("/:name/files", EmojiPackController, :delete_file)
end
# Pack info / downloading
scope "/packs" do
get("/", EmojiAPIController, :list)
get("/:name", EmojiAPIController, :show)
get("/:name/archive", EmojiAPIController, :archive)
pipe_through(:api)
get("/", EmojiPackController, :index)
get("/:name", EmojiPackController, :show)
get("/:name/archive", EmojiPackController, :archive)
end
end
@ -337,7 +338,7 @@ defmodule Pleroma.Web.Router do
get("/mascot", MascotController, :show)
put("/mascot", MascotController, :update)
post("/scrobble", ScrobbleController, :new_scrobble)
post("/scrobble", ScrobbleController, :create)
end
scope [] do
@ -357,7 +358,7 @@ defmodule Pleroma.Web.Router do
scope "/api/v1/pleroma", Pleroma.Web.PleromaAPI do
pipe_through(:api)
get("/accounts/:id/scrobbles", ScrobbleController, :user_scrobbles)
get("/accounts/:id/scrobbles", ScrobbleController, :index)
end
scope "/api/v1", Pleroma.Web.MastodonAPI do

View File

@ -27,8 +27,20 @@ defmodule Pleroma.Workers.AttachmentsCleanupWorker do
uploader = Pleroma.Config.get([Pleroma.Upload, :uploader])
prefix =
case Pleroma.Config.get([Pleroma.Upload, :base_url]) do
nil -> "media"
_ -> ""
end
base_url =
String.trim_trailing(
Pleroma.Config.get([Pleroma.Upload, :base_url], Pleroma.Web.base_url()),
"/"
)
# find all objects for copies of the attachments, name and actor doesn't matter here
delete_ids =
object_ids_and_hrefs =
from(o in Object,
where:
fragment(
@ -67,29 +79,28 @@ defmodule Pleroma.Workers.AttachmentsCleanupWorker do
|> Enum.map(fn {href, %{id: id, count: count}} ->
# only delete files that have single instance
with 1 <- count do
prefix =
case Pleroma.Config.get([Pleroma.Upload, :base_url]) do
nil -> "media"
_ -> ""
end
href
|> String.trim_leading("#{base_url}/#{prefix}")
|> uploader.delete_file()
base_url =
String.trim_trailing(
Pleroma.Config.get([Pleroma.Upload, :base_url], Pleroma.Web.base_url()),
"/"
)
file_path = String.trim_leading(href, "#{base_url}/#{prefix}")
uploader.delete_file(file_path)
{id, href}
else
_ -> {id, nil}
end
id
end)
from(o in Object, where: o.id in ^delete_ids)
object_ids = Enum.map(object_ids_and_hrefs, fn {id, _} -> id end)
from(o in Object, where: o.id in ^object_ids)
|> Repo.delete_all()
object_ids_and_hrefs
|> Enum.filter(fn {_, href} -> not is_nil(href) end)
|> Enum.map(&elem(&1, 1))
|> Pleroma.Web.MediaProxy.Invalidation.purge()
{:ok, :success}
end
def perform(%{"op" => "cleanup_attachments", "object" => _object}, _job), do: :ok
def perform(%{"op" => "cleanup_attachments", "object" => _object}, _job), do: {:ok, :skip}
end

View File

@ -155,7 +155,7 @@ defmodule Pleroma.Mixfile do
{:credo, "~> 1.1.0", only: [:dev, :test], runtime: false},
{:mock, "~> 0.3.3", only: :test},
{:crypt,
git: "https://github.com/msantos/crypt", ref: "1f2b58927ab57e72910191a7ebaeff984382a1d3"},
git: "https://github.com/msantos/crypt", ref: "f63a705f92c26955977ee62a313012e309a4d77a"},
{:cors_plug, "~> 1.5"},
{:ex_doc, "~> 0.21", only: :dev, runtime: false},
{:web_push_encryption, "~> 0.2.1"},

View File

@ -21,13 +21,13 @@
"cowlib": {:hex, :cowlib, "2.8.0", "fd0ff1787db84ac415b8211573e9a30a3ebe71b5cbff7f720089972b2319c8a4", [:rebar3], [], "hexpm", "79f954a7021b302186a950a32869dbc185523d99d3e44ce430cd1f3289f41ed4"},
"credo": {:hex, :credo, "1.1.5", "caec7a3cadd2e58609d7ee25b3931b129e739e070539ad1a0cd7efeeb47014f4", [:mix], [{:bunt, "~> 0.2.0", [hex: :bunt, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: false]}], "hexpm", "d0bbd3222607ccaaac5c0340f7f525c627ae4d7aee6c8c8c108922620c5b6446"},
"crontab": {:hex, :crontab, "1.1.8", "2ce0e74777dfcadb28a1debbea707e58b879e6aa0ffbf9c9bb540887bce43617", [:mix], [{:ecto, "~> 1.0 or ~> 2.0 or ~> 3.0", [hex: :ecto, repo: "hexpm", optional: true]}], "hexpm"},
"crypt": {:git, "https://github.com/msantos/crypt", "1f2b58927ab57e72910191a7ebaeff984382a1d3", [ref: "1f2b58927ab57e72910191a7ebaeff984382a1d3"]},
"crypt": {:git, "https://github.com/msantos/crypt", "f63a705f92c26955977ee62a313012e309a4d77a", [ref: "f63a705f92c26955977ee62a313012e309a4d77a"]},
"custom_base": {:hex, :custom_base, "0.2.1", "4a832a42ea0552299d81652aa0b1f775d462175293e99dfbe4d7dbaab785a706", [:mix], [], "hexpm", "8df019facc5ec9603e94f7270f1ac73ddf339f56ade76a721eaa57c1493ba463"},
"db_connection": {:hex, :db_connection, "2.2.1", "caee17725495f5129cb7faebde001dc4406796f12a62b8949f4ac69315080566", [:mix], [{:connection, "~> 1.0.2", [hex: :connection, repo: "hexpm", optional: false]}], "hexpm", "2b02ece62d9f983fcd40954e443b7d9e6589664380e5546b2b9b523cd0fb59e1"},
"decimal": {:hex, :decimal, "1.8.1", "a4ef3f5f3428bdbc0d35374029ffcf4ede8533536fa79896dd450168d9acdf3c", [:mix], [], "hexpm", "3cb154b00225ac687f6cbd4acc4b7960027c757a5152b369923ead9ddbca7aec"},
"deep_merge": {:hex, :deep_merge, "1.0.0", "b4aa1a0d1acac393bdf38b2291af38cb1d4a52806cf7a4906f718e1feb5ee961", [:mix], [], "hexpm", "ce708e5f094b9cd4e8f2be4f00d2f4250c4095be93f8cd6d018c753894885430"},
"earmark": {:hex, :earmark, "1.4.3", "364ca2e9710f6bff494117dbbd53880d84bebb692dafc3a78eb50aa3183f2bfd", [:mix], [], "hexpm", "8cf8a291ebf1c7b9539e3cddb19e9cef066c2441b1640f13c34c1d3cfc825fec"},
"ecto": {:hex, :ecto, "3.4.0", "a7a83ab8359bf816ce729e5e65981ce25b9fc5adfc89c2ea3980f4fed0bfd7c1", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}], "hexpm", "5eed18252f5b5bbadec56a24112b531343507dbe046273133176b12190ce19cc"},
"ecto": {:hex, :ecto, "3.4.4", "a2c881e80dc756d648197ae0d936216c0308370332c5e77a2325a10293eef845", [:mix], [{:decimal, "~> 1.6 or ~> 2.0", [hex: :decimal, repo: "hexpm", optional: false]}, {:jason, "~> 1.0", [hex: :jason, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "cc4bd3ad62abc3b21fb629f0f7a3dab23a192fca837d257dd08449fba7373561"},
"ecto_enum": {:hex, :ecto_enum, "1.4.0", "d14b00e04b974afc69c251632d1e49594d899067ee2b376277efd8233027aec8", [:mix], [{:ecto, ">= 3.0.0", [hex: :ecto, repo: "hexpm", optional: false]}, {:ecto_sql, "> 3.0.0", [hex: :ecto_sql, repo: "hexpm", optional: false]}, {:mariaex, ">= 0.0.0", [hex: :mariaex, repo: "hexpm", optional: true]}, {:postgrex, ">= 0.0.0", [hex: :postgrex, repo: "hexpm", optional: true]}], "hexpm", "8fb55c087181c2b15eee406519dc22578fa60dd82c088be376d0010172764ee4"},
"ecto_sql": {:hex, :ecto_sql, "3.3.4", "aa18af12eb875fbcda2f75e608b3bd534ebf020fc4f6448e4672fcdcbb081244", [:mix], [{:db_connection, "~> 2.2", [hex: :db_connection, repo: "hexpm", optional: false]}, {:ecto, "~> 3.4 or ~> 3.3.3", [hex: :ecto, repo: "hexpm", optional: false]}, {:myxql, "~> 0.3.0", [hex: :myxql, repo: "hexpm", optional: true]}, {:postgrex, "~> 0.15.0", [hex: :postgrex, repo: "hexpm", optional: true]}, {:telemetry, "~> 0.4.0", [hex: :telemetry, repo: "hexpm", optional: false]}], "hexpm", "5eccbdbf92e3c6f213007a82d5dbba4cd9bb659d1a21331f89f408e4c0efd7a8"},
"elixir_make": {:hex, :elixir_make, "0.6.0", "38349f3e29aff4864352084fc736fa7fa0f2995a819a737554f7ebd28b85aaab", [:mix], [], "hexpm", "d522695b93b7f0b4c0fcb2dfe73a6b905b1c301226a5a55cb42e5b14d509e050"},
@ -57,7 +57,7 @@
"httpoison": {:hex, :httpoison, "1.6.2", "ace7c8d3a361cebccbed19c283c349b3d26991eff73a1eaaa8abae2e3c8089b6", [:mix], [{:hackney, "~> 1.15 and >= 1.15.2", [hex: :hackney, repo: "hexpm", optional: false]}], "hexpm", "aa2c74bd271af34239a3948779612f87df2422c2fdcfdbcec28d9c105f0773fe"},
"idna": {:hex, :idna, "6.0.0", "689c46cbcdf3524c44d5f3dde8001f364cd7608a99556d8fbd8239a5798d4c10", [:rebar3], [{:unicode_util_compat, "0.4.1", [hex: :unicode_util_compat, repo: "hexpm", optional: false]}], "hexpm", "4bdd305eb64e18b0273864920695cb18d7a2021f31a11b9c5fbcd9a253f936e2"},
"inet_cidr": {:hex, :inet_cidr, "1.0.4", "a05744ab7c221ca8e395c926c3919a821eb512e8f36547c062f62c4ca0cf3d6e", [:mix], [], "hexpm", "64a2d30189704ae41ca7dbdd587f5291db5d1dda1414e0774c29ffc81088c1bc"},
"jason": {:hex, :jason, "1.2.0", "10043418c42d2493d0ee212d3fddd25d7ffe484380afad769a0a38795938e448", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "116747dbe057794c3a3e4e143b7c8390b29f634e16c78a7f59ba75bfa6852e7f"},
"jason": {:hex, :jason, "1.2.1", "12b22825e22f468c02eb3e4b9985f3d0cb8dc40b9bd704730efa11abd2708c44", [:mix], [{:decimal, "~> 1.0", [hex: :decimal, repo: "hexpm", optional: true]}], "hexpm", "b659b8571deedf60f79c5a608e15414085fa141344e2716fbd6988a084b5f993"},
"joken": {:hex, :joken, "2.2.0", "2daa1b12be05184aff7b5ace1d43ca1f81345962285fff3f88db74927c954d3a", [:mix], [{:jose, "~> 1.9", [hex: :jose, repo: "hexpm", optional: false]}], "hexpm", "b4f92e30388206f869dd25d1af628a1d99d7586e5cf0672f64d4df84c4d2f5e9"},
"jose": {:hex, :jose, "1.10.1", "16d8e460dae7203c6d1efa3f277e25b5af8b659febfc2f2eb4bacf87f128b80a", [:mix, :rebar3], [], "hexpm", "3c7ddc8a9394b92891db7c2771da94bf819834a1a4c92e30857b7d582e2f8257"},
"jumper": {:hex, :jumper, "1.0.1", "3c00542ef1a83532b72269fab9f0f0c82bf23a35e27d278bfd9ed0865cecabff", [:mix], [], "hexpm", "318c59078ac220e966d27af3646026db9b5a5e6703cb2aa3e26bcfaba65b7433"},

View File

@ -1,2 +1,2 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[2],{722:function(e,t,n){"use strict";n.r(t),n.d(t,"register",(function(){return s})),n.d(t,"setFocusTrapTest",(function(){return d})),n.d(t,"unregister",(function(){return l}));var r="a[href], area[href], input, select, textarea, button, iframe, object, embed, [contenteditable], [tabindex], video[controls], audio[controls], summary",o=["text","search","url","password","tel"],i=["checkbox","radio"],a=void 0;function c(e){for(var t=[],n=(function(e){if(!a)return;var t=e.parentElement;for(;t;){if(a(t))return t;t=t.parentElement}}(e)||document).querySelectorAll(r),o=n.length,i=0;i<o;i++){var c=n[i];c!==e&&(c.disabled||/^-/.test(c.getAttribute("tabindex")||"")||c.hasAttribute("inert")||!(c.offsetWidth>0||c.offsetHeight>0))||t.push(c)}return t}function u(e,t){var n=document.activeElement;if(!function(e,t){var n,r,i,a=e.tagName,c="TEXTAREA"===a,u="INPUT"===a&&-1!==o.indexOf(e.getAttribute("type").toLowerCase()),f=e.hasAttribute("contenteditable");if(!c&&!u&&!f)return!1;if(f){var s=getSelection();n=s.anchorOffset,r=s.focusOffset,i=e.textContent.length}else n=e.selectionStart,r=e.selectionEnd,i=e.value.length;return("ArrowLeft"!==t||n!==r||0!==n)&&("ArrowRight"!==t||n!==r||n!==i)}(n,t)){var r=c(n);if(r.length){var i=r.indexOf(n);("ArrowLeft"===t?r[i-1]||r[0]:r[i+1]||r[r.length-1]).focus(),e.preventDefault()}}}function f(e){if(!(e.altKey||e.metaKey||e.ctrlKey)){var t=e.key;switch(t){case"ArrowLeft":case"ArrowRight":u(e,t);break;case"Enter":!function(e){var t=document.activeElement;"INPUT"===t.tagName&&-1!==i.indexOf(t.getAttribute("type").toLowerCase())&&(t.click(),e.preventDefault())}(e)}}}function s(){addEventListener("keydown",f)}function l(){removeEventListener("keydown",f)}function d(e){a=e}}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[2],{738:function(e,t,n){"use strict";n.r(t),n.d(t,"register",(function(){return s})),n.d(t,"setFocusTrapTest",(function(){return d})),n.d(t,"unregister",(function(){return l}));var r="a[href], area[href], input, select, textarea, button, iframe, object, embed, [contenteditable], [tabindex], video[controls], audio[controls], summary",o=["text","search","url","password","tel"],i=["checkbox","radio"],a=void 0;function c(e){for(var t=[],n=(function(e){if(!a)return;var t=e.parentElement;for(;t;){if(a(t))return t;t=t.parentElement}}(e)||document).querySelectorAll(r),o=n.length,i=0;i<o;i++){var c=n[i];c!==e&&(c.disabled||/^-/.test(c.getAttribute("tabindex")||"")||c.hasAttribute("inert")||!(c.offsetWidth>0||c.offsetHeight>0))||t.push(c)}return t}function u(e,t){var n=document.activeElement;if(!function(e,t){var n,r,i,a=e.tagName,c="TEXTAREA"===a,u="INPUT"===a&&-1!==o.indexOf(e.getAttribute("type").toLowerCase()),f=e.hasAttribute("contenteditable");if(!c&&!u&&!f)return!1;if(f){var s=getSelection();n=s.anchorOffset,r=s.focusOffset,i=e.textContent.length}else n=e.selectionStart,r=e.selectionEnd,i=e.value.length;return("ArrowLeft"!==t||n!==r||0!==n)&&("ArrowRight"!==t||n!==r||n!==i)}(n,t)){var r=c(n);if(r.length){var i=r.indexOf(n);("ArrowLeft"===t?r[i-1]||r[0]:r[i+1]||r[r.length-1]).focus(),e.preventDefault()}}}function f(e){if(!(e.altKey||e.metaKey||e.ctrlKey)){var t=e.key;switch(t){case"ArrowLeft":case"ArrowRight":u(e,t);break;case"Enter":!function(e){var t=document.activeElement;"INPUT"===t.tagName&&-1!==i.indexOf(t.getAttribute("type").toLowerCase())&&(t.click(),e.preventDefault())}(e)}}}function s(){addEventListener("keydown",f)}function l(){removeEventListener("keydown",f)}function d(e){a=e}}}]);
//# sourceMappingURL=arrow-key-navigation.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -4,103 +4,69 @@
http://jedwatson.github.io/classnames
*/
/*!
* escape-html
* Copyright(c) 2012-2013 TJ Holowaychuk
* Copyright(c) 2015 Andreas Lubbe
* Copyright(c) 2015 Tiancheng "Timothy" Gu
* MIT Licensed
*/
/*!
* wavesurfer.js 3.3.1 (2020-01-14)
* https://github.com/katspaugh/wavesurfer.js
* @license BSD-3-Clause
*/
/*!****************************************!*\
!*** ./node_modules/debounce/index.js ***!
\****************************************/
/*! no static exports found */
/*!***********************************!*\
!*** ./src/drawer.canvasentry.js ***!
\***********************************/
/*! ./util/style */
/*! ./util/get-id */
/*!***********************!*\
!*** ./src/drawer.js ***!
\***********************/
/*! ./util */
/*!***********************************!*\
!*** ./src/drawer.multicanvas.js ***!
\***********************************/
/*! ./ajax */
/*! ./drawer */
/*! ./drawer.canvasentry */
/*!**************************************!*\
!*** ./src/mediaelement-webaudio.js ***!
\**************************************/
/*! ./drawer.multicanvas */
/*! ./mediaelement */
/*! ./extend */
/*!*****************************!*\
!*** ./src/mediaelement.js ***!
\*****************************/
/*! ./fetch */
/*! ./webaudio */
/*!**************************!*\
!*** ./src/peakcache.js ***!
\**************************/
/*!**************************!*\
!*** ./src/util/ajax.js ***!
\**************************/
/*! ./observer */
/*!****************************!*\
!*** ./src/util/extend.js ***!
\****************************/
/*!***************************!*\
!*** ./src/util/fetch.js ***!
\***************************/
/*!***************************!*\
!*** ./src/util/frame.js ***!
\***************************/
/*! ./request-animation-frame */
/*!****************************!*\
!*** ./src/util/get-id.js ***!
\****************************/
/*!***************************!*\
!*** ./src/util/index.js ***!
\***************************/
/*! ./ajax */
/*! ./frame */
/*! ./get-id */
/*! ./max */
/*! ./mediaelement */
/*! ./mediaelement-webaudio */
/*! ./min */
/*! ./extend */
/*! ./observer */
/*! ./style */
/*! ./frame */
/*! debounce */
/*! ./peakcache */
/*! ./prevent-click */
/*! ./fetch */
/*! ./request-animation-frame */
/*! ./style */
/*! ./util */
/*! ./util/get-id */
/*! ./util/style */
/*! ./webaudio */
/*! debounce */
/*! no static exports found */
/*!***********************!*\
!*** ./src/drawer.js ***!
\***********************/
/*!*************************!*\
!*** ./src/util/max.js ***!
@ -110,17 +76,29 @@
!*** ./src/util/min.js ***!
\*************************/
/*!******************************!*\
!*** ./src/util/observer.js ***!
\******************************/
/*!*************************!*\
!*** ./src/webaudio.js ***!
\*************************/
/*!***********************************!*\
!*** ./src/util/prevent-click.js ***!
\***********************************/
/*!**************************!*\
!*** ./src/peakcache.js ***!
\**************************/
/*!*********************************************!*\
!*** ./src/util/request-animation-frame.js ***!
\*********************************************/
/*!**************************!*\
!*** ./src/util/ajax.js ***!
\**************************/
/*!***************************!*\
!*** ./src/util/fetch.js ***!
\***************************/
/*!***************************!*\
!*** ./src/util/frame.js ***!
\***************************/
/*!***************************!*\
!*** ./src/util/index.js ***!
\***************************/
/*!***************************!*\
!*** ./src/util/style.js ***!
@ -130,20 +108,42 @@
!*** ./src/wavesurfer.js ***!
\***************************/
/*! ./drawer.multicanvas */
/*!****************************!*\
!*** ./src/util/extend.js ***!
\****************************/
/*! ./peakcache */
/*!****************************!*\
!*** ./src/util/get-id.js ***!
\****************************/
/*! ./mediaelement-webaudio */
/*!*****************************!*\
!*** ./src/mediaelement.js ***!
\*****************************/
/*!*************************!*\
!*** ./src/webaudio.js ***!
\*************************/
/*!******************************!*\
!*** ./src/util/observer.js ***!
\******************************/
/*!
* escape-html
* Copyright(c) 2012-2013 TJ Holowaychuk
* Copyright(c) 2015 Andreas Lubbe
* Copyright(c) 2015 Tiancheng "Timothy" Gu
* MIT Licensed
*/
/*!***********************************!*\
!*** ./src/drawer.canvasentry.js ***!
\***********************************/
/*!***********************************!*\
!*** ./src/drawer.multicanvas.js ***!
\***********************************/
/*!***********************************!*\
!*** ./src/util/prevent-click.js ***!
\***********************************/
/*!**************************************!*\
!*** ./src/mediaelement-webaudio.js ***!
\**************************************/
/*!****************************************!*\
!*** ./node_modules/debounce/index.js ***!
\****************************************/
/*!*********************************************!*\
!*** ./src/util/request-animation-frame.js ***!
\*********************************************/

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[8],{918:function(e,t){window.addEventListener("message",(function(e){var t=e.data||{};function n(){window.parent.postMessage({type:"setHeight",id:t.id,height:document.getElementsByTagName("html")[0].scrollHeight},"*")}window.parent&&"setHeight"===t.type&&(["interactive","complete"].includes(document.readyState)?n():document.addEventListener("DOMContentLoaded",n))}))}},[[918,0]]]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[8],{944:function(e,t){window.addEventListener("message",(function(e){var t=e.data||{};function n(){window.parent.postMessage({type:"setHeight",id:t.id,height:document.getElementsByTagName("html")[0].scrollHeight},"*")}window.parent&&"setHeight"===t.type&&(["interactive","complete"].includes(document.readyState)?n():document.addEventListener("DOMContentLoaded",n))}))}},[[944,0]]]);
//# sourceMappingURL=embed.js.map

View File

@ -1,2 +1,2 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[9],{919:function(n,o,w){"use strict";w.r(o);w(920)},920:function(n,o,w){}},[[919,0]]]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[9],{945:function(n,o,w){"use strict";w.r(o);w(946)},946:function(n,o,w){}},[[945,0]]]);
//# sourceMappingURL=mailer.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[13],{786:function(n,r,i){"use strict";i.r(r);var o=i(1055);i.d(r,"Picker",(function(){return o.a}));var c=i(1032);i.d(r,"Emoji",(function(){return c.a}))}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[13],{812:function(n,r,i){"use strict";i.r(r);var o=i(1082);i.d(r,"Picker",(function(){return o.a}));var c=i(1058);i.d(r,"Emoji",(function(){return c.a}))}}]);
//# sourceMappingURL=emoji_picker.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[16],{793:function(t,a,e){"use strict";e.r(a),e.d(a,"default",(function(){return _}));var s,o,i,c=e(0),n=e(2),p=e(7),r=e(1),u=(e(3),e(13)),d=e(14),l=e.n(d),h=e(5),b=e.n(h),m=e(25),j=e(33),I=e(1038),O=e(300),f=e(731),w=e(1057),g=e(738),v=e(4),R=e(18),y=e(6),M=e(291),L=e(1030),S=Object(v.List)(),_=Object(u.connect)((function(t,a){var e=a.params.accountId,s=a.withReplies,o=void 0!==s&&s,i=o?e+":with_replies":e;return{isAccount:!!t.getIn(["accounts",e]),statusIds:t.getIn(["timelines","account:"+i,"items"],S),featuredStatusIds:o?Object(v.List)():t.getIn(["timelines","account:"+e+":pinned","items"],S),isLoading:t.getIn(["timelines","account:"+i,"isLoading"]),hasMore:t.getIn(["timelines","account:"+i,"hasMore"]),blockedBy:t.getIn(["relationships",e,"blocked_by"],!1)}}))((i=o=function(t){function a(){for(var a,e=arguments.length,s=new Array(e),o=0;o<e;o++)s[o]=arguments[o];return a=t.call.apply(t,[this].concat(s))||this,Object(r.a)(Object(n.a)(a),"handleLoadMore",(function(t){a.props.dispatch(Object(j.q)(a.props.params.accountId,{maxId:t,withReplies:a.props.withReplies}))})),a}Object(p.a)(a,t);var e=a.prototype;return e.componentWillMount=function(){var t=this.props,a=t.params.accountId,e=t.withReplies;this.props.dispatch(Object(m.A)(a)),this.props.dispatch(Object(M.d)(a)),e||this.props.dispatch(Object(j.o)(a)),this.props.dispatch(Object(j.q)(a,{withReplies:e}))},e.componentWillReceiveProps=function(t){(t.params.accountId!==this.props.params.accountId&&t.params.accountId||t.withReplies!==this.props.withReplies)&&(this.props.dispatch(Object(m.A)(t.params.accountId)),this.props.dispatch(Object(M.d)(t.params.accountId)),t.withReplies||this.props.dispatch(Object(j.o)(t.params.accountId)),this.props.dispatch(Object(j.q)(t.params.accountId,{withReplies:t.params.withReplies})))},e.render=function(){var t=this.props,a=t.shouldUpdateScroll,e=t.statusIds,s=t.featuredStatusIds,o=t.isLoading,i=t.hasMore,n=t.blockedBy,p=t.isAccount,r=t.multiColumn;if(!p)return Object(c.a)(f.a,{},void 0,Object(c.a)(g.a,{multiColumn:r}),Object(c.a)(L.a,{}));if(!e&&o)return Object(c.a)(f.a,{},void 0,Object(c.a)(O.a,{}));var u=n?Object(c.a)(y.b,{id:"empty_column.account_unavailable",defaultMessage:"Profile unavailable"}):Object(c.a)(y.b,{id:"empty_column.account_timeline",defaultMessage:"No toots here!"});return Object(c.a)(f.a,{},void 0,Object(c.a)(g.a,{multiColumn:r}),Object(c.a)(I.a,{prepend:Object(c.a)(w.a,{accountId:this.props.params.accountId}),alwaysPrepend:!0,scrollKey:"account_timeline",statusIds:n?S:e,featuredStatusIds:s,isLoading:o,hasMore:i,onLoadMore:this.handleLoadMore,shouldUpdateScroll:a,emptyMessage:u,bindToDocument:!r}))},a}(R.a),Object(r.a)(o,"propTypes",{params:b.a.object.isRequired,dispatch:b.a.func.isRequired,shouldUpdateScroll:b.a.func,statusIds:l.a.list,featuredStatusIds:l.a.list,isLoading:b.a.bool,hasMore:b.a.bool,withReplies:b.a.bool,blockedBy:b.a.bool,isAccount:b.a.bool,multiColumn:b.a.bool}),s=i))||s}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[16],{819:function(t,a,e){"use strict";e.r(a),e.d(a,"default",(function(){return _}));var s,o,i,c=e(0),n=e(2),p=(e(9),e(6),e(8)),r=e(1),u=(e(3),e(15)),d=e(16),l=e.n(d),h=e(5),b=e.n(h),m=e(26),j=e(36),I=e(1065),O=e(306),f=e(757),w=e(1084),v=e(764),g=e(4),R=e(21),y=e(7),M=e(291),L=e(1057);var S=Object(g.List)(),_=Object(u.connect)((function(t,a){var e=a.params.accountId,s=a.withReplies,o=void 0!==s&&s,i=o?e+":with_replies":e;return{isAccount:!!t.getIn(["accounts",e]),statusIds:t.getIn(["timelines","account:"+i,"items"],S),featuredStatusIds:o?Object(g.List)():t.getIn(["timelines","account:"+e+":pinned","items"],S),isLoading:t.getIn(["timelines","account:"+i,"isLoading"]),hasMore:t.getIn(["timelines","account:"+i,"hasMore"]),blockedBy:t.getIn(["relationships",e,"blocked_by"],!1)}}))((i=o=function(t){Object(p.a)(e,t);var a;a=e;function e(){for(var a,e=arguments.length,s=new Array(e),o=0;o<e;o++)s[o]=arguments[o];return a=t.call.apply(t,[this].concat(s))||this,Object(r.a)(Object(n.a)(a),"handleLoadMore",(function(t){a.props.dispatch(Object(j.q)(a.props.params.accountId,{maxId:t,withReplies:a.props.withReplies}))})),a}var s=e.prototype;return s.componentWillMount=function(){var t=this.props,a=t.params.accountId,e=t.withReplies;this.props.dispatch(Object(m.A)(a)),this.props.dispatch(Object(M.d)(a)),e||this.props.dispatch(Object(j.o)(a)),this.props.dispatch(Object(j.q)(a,{withReplies:e}))},s.componentWillReceiveProps=function(t){(t.params.accountId!==this.props.params.accountId&&t.params.accountId||t.withReplies!==this.props.withReplies)&&(this.props.dispatch(Object(m.A)(t.params.accountId)),this.props.dispatch(Object(M.d)(t.params.accountId)),t.withReplies||this.props.dispatch(Object(j.o)(t.params.accountId)),this.props.dispatch(Object(j.q)(t.params.accountId,{withReplies:t.params.withReplies})))},s.render=function(){var t=this.props,a=t.shouldUpdateScroll,e=t.statusIds,s=t.featuredStatusIds,o=t.isLoading,i=t.hasMore,n=t.blockedBy,p=t.isAccount,r=t.multiColumn;if(!p)return Object(c.a)(f.a,{},void 0,Object(c.a)(v.a,{multiColumn:r}),Object(c.a)(L.a,{}));if(!e&&o)return Object(c.a)(f.a,{},void 0,Object(c.a)(O.a,{}));var u=n?Object(c.a)(y.b,{id:"empty_column.account_unavailable",defaultMessage:"Profile unavailable"}):Object(c.a)(y.b,{id:"empty_column.account_timeline",defaultMessage:"No toots here!"});return(Object(c.a)(f.a,{},void 0,Object(c.a)(v.a,{multiColumn:r}),Object(c.a)(I.a,{prepend:Object(c.a)(w.a,{accountId:this.props.params.accountId}),alwaysPrepend:!0,scrollKey:"account_timeline",statusIds:n?S:e,featuredStatusIds:s,isLoading:o,hasMore:i,onLoadMore:this.handleLoadMore,shouldUpdateScroll:a,emptyMessage:u,bindToDocument:!r,timelineId:"account"})))},e}(R.a),Object(r.a)(o,"propTypes",{params:b.a.object.isRequired,dispatch:b.a.func.isRequired,shouldUpdateScroll:b.a.func,statusIds:l.a.list,featuredStatusIds:l.a.list,isLoading:b.a.bool,hasMore:b.a.bool,withReplies:b.a.bool,blockedBy:b.a.bool,isAccount:b.a.bool,multiColumn:b.a.bool}),s=i))||s}}]);
//# sourceMappingURL=account_timeline.js.map

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[17],{801:function(e,t,o){"use strict";o.r(t),o.d(t,"default",(function(){return q}));var a,n,c,s=o(0),r=o(2),i=o(7),u=o(1),l=o(62),d=o.n(l),b=(o(3),o(13)),p=o(6),h=o(18),f=o(14),j=o.n(f),O=o(5),m=o.n(O),g=o(300),M=o(731),k=o(737),v=o(1026),y=o(226),w=o(1023),I=Object(p.f)({heading:{id:"column.blocks",defaultMessage:"Blocked users"}}),q=Object(b.connect)((function(e){return{accountIds:e.getIn(["user_lists","blocks","items"]),hasMore:!!e.getIn(["user_lists","blocks","next"])}}))(a=Object(p.g)((c=n=function(e){function t(){for(var t,o=arguments.length,a=new Array(o),n=0;n<o;n++)a[n]=arguments[n];return t=e.call.apply(e,[this].concat(a))||this,Object(u.a)(Object(r.a)(t),"handleLoadMore",d()((function(){t.props.dispatch(Object(y.d)())}),300,{leading:!0})),t}Object(i.a)(t,e);var o=t.prototype;return o.componentWillMount=function(){this.props.dispatch(Object(y.e)())},o.render=function(){var e=this.props,t=e.intl,o=e.accountIds,a=e.shouldUpdateScroll,n=e.hasMore,c=e.multiColumn;if(!o)return Object(s.a)(M.a,{},void 0,Object(s.a)(g.a,{}));var r=Object(s.a)(p.b,{id:"empty_column.blocks",defaultMessage:"You haven't blocked any users yet."});return Object(s.a)(M.a,{bindToDocument:!c,icon:"ban",heading:t.formatMessage(I.heading)},void 0,Object(s.a)(k.a,{}),Object(s.a)(w.a,{scrollKey:"blocks",onLoadMore:this.handleLoadMore,hasMore:n,shouldUpdateScroll:a,emptyMessage:r,bindToDocument:!c},void 0,o.map((function(e){return Object(s.a)(v.a,{id:e},e)}))))},t}(h.a),Object(u.a)(n,"propTypes",{params:m.a.object.isRequired,dispatch:m.a.func.isRequired,shouldUpdateScroll:m.a.func,accountIds:j.a.list,hasMore:m.a.bool,intl:m.a.object.isRequired,multiColumn:m.a.bool}),a=c))||a)||a}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[17],{827:function(e,t,a){"use strict";a.r(t),a.d(t,"default",(function(){return q}));var o,n,c,s=a(0),r=a(2),i=(a(9),a(6),a(8)),u=a(1),l=a(65),d=a.n(l),b=(a(3),a(15)),p=a(7),h=a(21),f=a(16),j=a.n(f),O=a(5),m=a.n(O),g=a(306),M=a(757),v=a(763),k=a(1053),y=a(230),w=a(1049);var I=Object(p.f)({heading:{id:"column.blocks",defaultMessage:"Blocked users"}}),q=Object(b.connect)((function(e){return{accountIds:e.getIn(["user_lists","blocks","items"]),hasMore:!!e.getIn(["user_lists","blocks","next"])}}))(o=Object(p.g)((c=n=function(e){Object(i.a)(a,e);var t;t=a;function a(){for(var t,a=arguments.length,o=new Array(a),n=0;n<a;n++)o[n]=arguments[n];return t=e.call.apply(e,[this].concat(o))||this,Object(u.a)(Object(r.a)(t),"handleLoadMore",d()((function(){t.props.dispatch(Object(y.d)())}),300,{leading:!0})),t}var o=a.prototype;return o.componentWillMount=function(){this.props.dispatch(Object(y.e)())},o.render=function(){var e=this.props,t=e.intl,a=e.accountIds,o=e.shouldUpdateScroll,n=e.hasMore,c=e.multiColumn;if(!a)return Object(s.a)(M.a,{},void 0,Object(s.a)(g.a,{}));var r=Object(s.a)(p.b,{id:"empty_column.blocks",defaultMessage:"You haven't blocked any users yet."});return(Object(s.a)(M.a,{bindToDocument:!c,icon:"ban",heading:t.formatMessage(I.heading)},void 0,Object(s.a)(v.a,{}),Object(s.a)(w.a,{scrollKey:"blocks",onLoadMore:this.handleLoadMore,hasMore:n,shouldUpdateScroll:o,emptyMessage:r,bindToDocument:!c},void 0,a.map((function(e){return Object(s.a)(k.a,{id:e},e)})))))},a}(h.a),Object(u.a)(n,"propTypes",{params:m.a.object.isRequired,dispatch:m.a.func.isRequired,shouldUpdateScroll:m.a.func,accountIds:j.a.list,hasMore:m.a.bool,intl:m.a.object.isRequired,multiColumn:m.a.bool}),o=c))||o)||o}}]);
//# sourceMappingURL=blocks.js.map

View File

@ -1 +1 @@
{"version":3,"sources":["webpack:///app/javascript/tank/sources/git/git.pleroma.social/pleroma/mastofe/app/javascript/mastodon/features/blocks/index.js"],"names":["messages","defineMessages","heading","Blocks","connect","state","accountIds","getIn","hasMore","injectIntl","props","dispatch","expandBlocks","leading","componentWillMount","this","fetchBlocks","render","intl","shouldUpdateScroll","multiColumn","emptyMessage","id","defaultMessage","bindToDocument","icon","formatMessage","scrollKey","onLoadMore","handleLoadMore","map","ImmutablePureComponent","params","PropTypes","object","isRequired","func","ImmutablePropTypes","list","bool"],"mappings":"wTAcMA,EAAWC,YAAe,CAC9BC,QAAQ,CAAD,qDAUHC,EAFUC,mBALQ,SAAAC,GAAK,MAAK,CAChCC,WAAYD,EAAME,MAAM,CAAC,aAAc,SAAU,UACjDC,UAAWH,EAAME,MAAM,CAAC,aAAc,SAAU,Y,GAIjDE,a,mMAiBkB,KAAS,WACxB,EAAKC,MAAMC,SAASC,iBACnB,IAAK,CAAEC,SAAS,K,8CANnBC,mBAAA,WACEC,KAAKL,MAAMC,SAASK,gB,EAOtBC,OAAA,WAAW,IAAD,EAC+DF,KAAKL,MAApEQ,EADA,EACAA,KAAMZ,EADN,EACMA,WAAYa,EADlB,EACkBA,mBAAoBX,EADtC,EACsCA,QAASY,EAD/C,EAC+CA,YAEvD,IAAKd,EACH,OACE,YAAC,IAAD,UACE,YAAC,IAAD,KAKN,IAAMe,EAAe,YAAC,IAAD,CAAkBC,GAAG,sBAAsBC,eAAe,uCAE/E,OACE,YAAC,IAAD,CAAQC,gBAAiBJ,EAAaK,KAAK,MAAMvB,QAASgB,EAAKQ,cAAc1B,EAASE,eAAtF,EACE,YAAC,IAAD,IACA,YAAC,IAAD,CACEyB,UAAU,SACVC,WAAYb,KAAKc,eACjBrB,QAASA,EACTW,mBAAoBA,EACpBE,aAAcA,EACdG,gBAAiBJ,QANnB,EAQGd,EAAWwB,KAAI,SAAAR,GAAE,OAChB,YAAC,IAAD,CAA2BA,GAAIA,GAARA,S,GA7CdS,K,0BAEA,CACjBC,OAAQC,IAAUC,OAAOC,WACzBxB,SAAUsB,IAAUG,KAAKD,WACzBhB,mBAAoBc,IAAUG,KAC9B9B,WAAY+B,IAAmBC,KAC/B9B,QAASyB,IAAUM,KACnBrB,KAAMe,IAAUC,OAAOC,WACvBf,YAAaa,IAAUM,O","file":"features/blocks.js","sourcesContent":["import React from 'react';\nimport { connect } from 'react-redux';\nimport { defineMessages, injectIntl, FormattedMessage } from 'react-intl';\nimport ImmutablePureComponent from 'react-immutable-pure-component';\nimport ImmutablePropTypes from 'react-immutable-proptypes';\nimport { debounce } from 'lodash';\nimport PropTypes from 'prop-types';\nimport LoadingIndicator from '../../components/loading_indicator';\nimport Column from '../ui/components/column';\nimport ColumnBackButtonSlim from '../../components/column_back_button_slim';\nimport AccountContainer from '../../containers/account_container';\nimport { fetchBlocks, expandBlocks } from '../../actions/blocks';\nimport ScrollableList from '../../components/scrollable_list';\n\nconst messages = defineMessages({\n heading: { id: 'column.blocks', defaultMessage: 'Blocked users' },\n});\n\nconst mapStateToProps = state => ({\n accountIds: state.getIn(['user_lists', 'blocks', 'items']),\n hasMore: !!state.getIn(['user_lists', 'blocks', 'next']),\n});\n\nexport default @connect(mapStateToProps)\n@injectIntl\nclass Blocks extends ImmutablePureComponent {\n\n static propTypes = {\n params: PropTypes.object.isRequired,\n dispatch: PropTypes.func.isRequired,\n shouldUpdateScroll: PropTypes.func,\n accountIds: ImmutablePropTypes.list,\n hasMore: PropTypes.bool,\n intl: PropTypes.object.isRequired,\n multiColumn: PropTypes.bool,\n };\n\n componentWillMount () {\n this.props.dispatch(fetchBlocks());\n }\n\n handleLoadMore = debounce(() => {\n this.props.dispatch(expandBlocks());\n }, 300, { leading: true });\n\n render () {\n const { intl, accountIds, shouldUpdateScroll, hasMore, multiColumn } = this.props;\n\n if (!accountIds) {\n return (\n <Column>\n <LoadingIndicator />\n </Column>\n );\n }\n\n const emptyMessage = <FormattedMessage id='empty_column.blocks' defaultMessage=\"You haven't blocked any users yet.\" />;\n\n return (\n <Column bindToDocument={!multiColumn} icon='ban' heading={intl.formatMessage(messages.heading)}>\n <ColumnBackButtonSlim />\n <ScrollableList\n scrollKey='blocks'\n onLoadMore={this.handleLoadMore}\n hasMore={hasMore}\n shouldUpdateScroll={shouldUpdateScroll}\n emptyMessage={emptyMessage}\n bindToDocument={!multiColumn}\n >\n {accountIds.map(id =>\n <AccountContainer key={id} id={id} />\n )}\n </ScrollableList>\n </Column>\n );\n }\n\n}\n"],"sourceRoot":""}
{"version":3,"sources":["webpack:///app/javascript/tank/sources/git/git.pleroma.social/pleroma/mastofe/app/javascript/mastodon/features/blocks/index.js"],"names":["messages","defineMessages","heading","Blocks","connect","state","accountIds","getIn","hasMore","injectIntl","props","dispatch","expandBlocks","leading","componentWillMount","this","fetchBlocks","render","intl","shouldUpdateScroll","multiColumn","emptyMessage","id","defaultMessage","bindToDocument","icon","formatMessage","scrollKey","onLoadMore","handleLoadMore","map","ImmutablePureComponent","params","PropTypes","object","isRequired","func","ImmutablePropTypes","list","bool"],"mappings":"oUAcA,IAAMA,EAAWC,YAAe,CAC9BC,QAAQ,CAAD,qDAUHC,EAFUC,mBALQ,SAAAC,GAAK,MAAK,CAChCC,WAAYD,EAAME,MAAM,CAAC,aAAc,SAAU,UACjDC,UAAWH,EAAME,MAAM,CAAC,aAAc,SAAU,Y,GAIjDE,a,8NAiBkB,KAAS,WACxB,EAAKC,MAAMC,SAASC,iBACnB,IAAK,CAAEC,SAAS,K,6BANnBC,mBAAA,WACEC,KAAKL,MAAMC,SAASK,gB,EAOtBC,OAAA,WAAW,IAAD,EAC+DF,KAAKL,MAApEQ,EADA,EACAA,KAAMZ,EADN,EACMA,WAAYa,EADlB,EACkBA,mBAAoBX,EADtC,EACsCA,QAASY,EAD/C,EAC+CA,YAEvD,IAAKd,EACH,OACE,YAAC,IAAD,UACE,YAAC,IAAD,KAKN,IAAMe,EAAe,YAAC,IAAD,CAAkBC,GAAG,sBAAsBC,eAAe,uCAE/E,OACE,YAAC,IAAD,CAAQC,gBAAiBJ,EAAaK,KAAK,MAAMvB,QAASgB,EAAKQ,cAAc1B,EAASE,eAAtF,EACE,YAAC,IAAD,IACA,YAAC,IAAD,CACEyB,UAAU,SACVC,WAAYb,KAAKc,eACjBrB,QAASA,EACTW,mBAAoBA,EACpBE,aAAcA,EACdG,gBAAiBJ,QANnB,EAQGd,EAAWwB,KAAI,SAAAR,GAAE,OAChB,YAAC,IAAD,CAA2BA,GAAIA,GAARA,U,GA7CdS,K,0BAEA,CACjBC,OAAQC,IAAUC,OAAOC,WACzBxB,SAAUsB,IAAUG,KAAKD,WACzBhB,mBAAoBc,IAAUG,KAC9B9B,WAAY+B,IAAmBC,KAC/B9B,QAASyB,IAAUM,KACnBrB,KAAMe,IAAUC,OAAOC,WACvBf,YAAaa,IAAUM,O","file":"features/blocks.js","sourcesContent":["import React from 'react';\nimport { connect } from 'react-redux';\nimport { defineMessages, injectIntl, FormattedMessage } from 'react-intl';\nimport ImmutablePureComponent from 'react-immutable-pure-component';\nimport ImmutablePropTypes from 'react-immutable-proptypes';\nimport { debounce } from 'lodash';\nimport PropTypes from 'prop-types';\nimport LoadingIndicator from '../../components/loading_indicator';\nimport Column from '../ui/components/column';\nimport ColumnBackButtonSlim from '../../components/column_back_button_slim';\nimport AccountContainer from '../../containers/account_container';\nimport { fetchBlocks, expandBlocks } from '../../actions/blocks';\nimport ScrollableList from '../../components/scrollable_list';\n\nconst messages = defineMessages({\n heading: { id: 'column.blocks', defaultMessage: 'Blocked users' },\n});\n\nconst mapStateToProps = state => ({\n accountIds: state.getIn(['user_lists', 'blocks', 'items']),\n hasMore: !!state.getIn(['user_lists', 'blocks', 'next']),\n});\n\nexport default @connect(mapStateToProps)\n@injectIntl\nclass Blocks extends ImmutablePureComponent {\n\n static propTypes = {\n params: PropTypes.object.isRequired,\n dispatch: PropTypes.func.isRequired,\n shouldUpdateScroll: PropTypes.func,\n accountIds: ImmutablePropTypes.list,\n hasMore: PropTypes.bool,\n intl: PropTypes.object.isRequired,\n multiColumn: PropTypes.bool,\n };\n\n componentWillMount () {\n this.props.dispatch(fetchBlocks());\n }\n\n handleLoadMore = debounce(() => {\n this.props.dispatch(expandBlocks());\n }, 300, { leading: true });\n\n render () {\n const { intl, accountIds, shouldUpdateScroll, hasMore, multiColumn } = this.props;\n\n if (!accountIds) {\n return (\n <Column>\n <LoadingIndicator />\n </Column>\n );\n }\n\n const emptyMessage = <FormattedMessage id='empty_column.blocks' defaultMessage=\"You haven't blocked any users yet.\" />;\n\n return (\n <Column bindToDocument={!multiColumn} icon='ban' heading={intl.formatMessage(messages.heading)}>\n <ColumnBackButtonSlim />\n <ScrollableList\n scrollKey='blocks'\n onLoadMore={this.handleLoadMore}\n hasMore={hasMore}\n shouldUpdateScroll={shouldUpdateScroll}\n emptyMessage={emptyMessage}\n bindToDocument={!multiColumn}\n >\n {accountIds.map(id =>\n <AccountContainer key={id} id={id} />,\n )}\n </ScrollableList>\n </Column>\n );\n }\n\n}\n"],"sourceRoot":""}

View File

@ -1,2 +1,2 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[18],{800:function(t,e,o){"use strict";o.r(e),o.d(e,"default",(function(){return C}));var a,n,s,i=o(0),c=o(2),l=o(7),r=o(1),d=o(62),u=o.n(d),b=o(3),h=o.n(b),p=o(13),m=o(5),k=o.n(m),O=o(14),f=o.n(O),j=o(205),g=o(731),M=o(733),I=o(250),v=o(1038),w=o(6),y=o(18),L=Object(w.f)({heading:{id:"column.bookmarks",defaultMessage:"Bookmarks"}}),C=Object(p.connect)((function(t){return{statusIds:t.getIn(["status_lists","bookmarks","items"]),isLoading:t.getIn(["status_lists","bookmarks","isLoading"],!0),hasMore:!!t.getIn(["status_lists","bookmarks","next"])}}))(a=Object(w.g)((s=n=function(t){function e(){for(var e,o=arguments.length,a=new Array(o),n=0;n<o;n++)a[n]=arguments[n];return e=t.call.apply(t,[this].concat(a))||this,Object(r.a)(Object(c.a)(e),"handlePin",(function(){var t=e.props,o=t.columnId,a=t.dispatch;a(o?Object(I.h)(o):Object(I.e)("BOOKMARKS",{}))})),Object(r.a)(Object(c.a)(e),"handleMove",(function(t){var o=e.props,a=o.columnId;(0,o.dispatch)(Object(I.g)(a,t))})),Object(r.a)(Object(c.a)(e),"handleHeaderClick",(function(){e.column.scrollTop()})),Object(r.a)(Object(c.a)(e),"setRef",(function(t){e.column=t})),Object(r.a)(Object(c.a)(e),"handleLoadMore",u()((function(){e.props.dispatch(Object(j.g)())}),300,{leading:!0})),e}Object(l.a)(e,t);var o=e.prototype;return o.componentWillMount=function(){this.props.dispatch(Object(j.h)())},o.render=function(){var t=this.props,e=t.intl,o=t.shouldUpdateScroll,a=t.statusIds,n=t.columnId,s=t.multiColumn,c=t.hasMore,l=t.isLoading,r=!!n,d=Object(i.a)(w.b,{id:"empty_column.bookmarked_statuses",defaultMessage:"You don't have any bookmarked toots yet. When you bookmark one, it will show up here."});return h.a.createElement(g.a,{bindToDocument:!s,ref:this.setRef,label:e.formatMessage(L.heading)},Object(i.a)(M.a,{icon:"bookmark",title:e.formatMessage(L.heading),onPin:this.handlePin,onMove:this.handleMove,onClick:this.handleHeaderClick,pinned:r,multiColumn:s,showBackButton:!0}),Object(i.a)(v.a,{trackScroll:!r,statusIds:a,scrollKey:"bookmarked_statuses-"+n,hasMore:c,isLoading:l,onLoadMore:this.handleLoadMore,shouldUpdateScroll:o,emptyMessage:d,bindToDocument:!s}))},e}(y.a),Object(r.a)(n,"propTypes",{dispatch:k.a.func.isRequired,shouldUpdateScroll:k.a.func,statusIds:f.a.list.isRequired,intl:k.a.object.isRequired,columnId:k.a.string,multiColumn:k.a.bool,hasMore:k.a.bool,isLoading:k.a.bool}),a=s))||a)||a}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[18],{826:function(t,e,o){"use strict";o.r(e),o.d(e,"default",(function(){return C}));var a,n,s,i=o(0),c=o(2),r=(o(9),o(6),o(8)),l=o(1),d=o(65),u=o.n(d),b=o(3),h=o.n(b),p=o(15),m=o(5),k=o.n(m),O=o(16),f=o.n(O),j=o(209),g=o(757),M=o(759),v=o(253),I=o(1065),w=o(7),y=o(21);var L=Object(w.f)({heading:{id:"column.bookmarks",defaultMessage:"Bookmarks"}}),C=Object(p.connect)((function(t){return{statusIds:t.getIn(["status_lists","bookmarks","items"]),isLoading:t.getIn(["status_lists","bookmarks","isLoading"],!0),hasMore:!!t.getIn(["status_lists","bookmarks","next"])}}))(a=Object(w.g)((s=n=function(t){Object(r.a)(o,t);var e;e=o;function o(){for(var e,o=arguments.length,a=new Array(o),n=0;n<o;n++)a[n]=arguments[n];return e=t.call.apply(t,[this].concat(a))||this,Object(l.a)(Object(c.a)(e),"handlePin",(function(){var t=e.props,o=t.columnId,a=t.dispatch;a(o?Object(v.h)(o):Object(v.e)("BOOKMARKS",{}))})),Object(l.a)(Object(c.a)(e),"handleMove",(function(t){var o=e.props,a=o.columnId;(0,o.dispatch)(Object(v.g)(a,t))})),Object(l.a)(Object(c.a)(e),"handleHeaderClick",(function(){e.column.scrollTop()})),Object(l.a)(Object(c.a)(e),"setRef",(function(t){e.column=t})),Object(l.a)(Object(c.a)(e),"handleLoadMore",u()((function(){e.props.dispatch(Object(j.g)())}),300,{leading:!0})),e}var a=o.prototype;return a.componentWillMount=function(){this.props.dispatch(Object(j.h)())},a.render=function(){var t=this.props,e=t.intl,o=t.shouldUpdateScroll,a=t.statusIds,n=t.columnId,s=t.multiColumn,c=t.hasMore,r=t.isLoading,l=!!n,d=Object(i.a)(w.b,{id:"empty_column.bookmarked_statuses",defaultMessage:"You don't have any bookmarked toots yet. When you bookmark one, it will show up here."});return h.a.createElement(g.a,{bindToDocument:!s,ref:this.setRef,label:e.formatMessage(L.heading)},Object(i.a)(M.a,{icon:"bookmark",title:e.formatMessage(L.heading),onPin:this.handlePin,onMove:this.handleMove,onClick:this.handleHeaderClick,pinned:l,multiColumn:s,showBackButton:!0}),Object(i.a)(I.a,{trackScroll:!l,statusIds:a,scrollKey:"bookmarked_statuses-"+n,hasMore:c,isLoading:r,onLoadMore:this.handleLoadMore,shouldUpdateScroll:o,emptyMessage:d,bindToDocument:!s}))},o}(y.a),Object(l.a)(n,"propTypes",{dispatch:k.a.func.isRequired,shouldUpdateScroll:k.a.func,statusIds:f.a.list.isRequired,intl:k.a.object.isRequired,columnId:k.a.string,multiColumn:k.a.bool,hasMore:k.a.bool,isLoading:k.a.bool}),a=s))||a)||a}}]);
//# sourceMappingURL=bookmarked_statuses.js.map

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[19],{835:function(e,t,n){"use strict";n.r(t);var o,i,c,a=n(0),l=n(2),d=n(7),r=n(1),s=n(3),u=n.n(s),m=n(13),p=n(6),h=n(5),b=n.n(h),f=n(1036),y=n(736),j=n(733),O=n(33),M=n(250),g=n(1139),v=n(70),I=Object(m.connect)((function(e,t){var n=t.columnId,o=e.getIn(["settings","columns"]),i=o.findIndex((function(e){return e.get("uuid")===n}));return{settings:n&&i>=0?o.get(i).get("params"):e.getIn(["settings","community"])}}),(function(e,t){var n=t.columnId;return{onChange:function(t,o){e(n?Object(M.f)(n,t,o):Object(v.c)(["community"].concat(t),o))}}}))(g.a),C=n(740);n.d(t,"default",(function(){return U}));var w=Object(p.f)({title:{id:"column.community",defaultMessage:"Local timeline"}}),U=Object(m.connect)((function(e,t){var n=t.columnId,o=n,i=e.getIn(["settings","columns"]),c=i.findIndex((function(e){return e.get("uuid")===o})),a=n&&c>=0?i.get(c).getIn(["params","other","onlyMedia"]):e.getIn(["settings","community","other","onlyMedia"]),l=e.getIn(["timelines","community"+(a?":media":"")]);return{hasUnread:!!l&&l.get("unread")>0,onlyMedia:a}}))(o=Object(p.g)((c=i=function(e){function t(){for(var t,n=arguments.length,o=new Array(n),i=0;i<n;i++)o[i]=arguments[i];return t=e.call.apply(e,[this].concat(o))||this,Object(r.a)(Object(l.a)(t),"handlePin",(function(){var e=t.props,n=e.columnId,o=e.dispatch,i=e.onlyMedia;o(n?Object(M.h)(n):Object(M.e)("COMMUNITY",{other:{onlyMedia:i}}))})),Object(r.a)(Object(l.a)(t),"handleMove",(function(e){var n=t.props,o=n.columnId;(0,n.dispatch)(Object(M.g)(o,e))})),Object(r.a)(Object(l.a)(t),"handleHeaderClick",(function(){t.column.scrollTop()})),Object(r.a)(Object(l.a)(t),"setRef",(function(e){t.column=e})),Object(r.a)(Object(l.a)(t),"handleLoadMore",(function(e){var n=t.props,o=n.dispatch,i=n.onlyMedia;o(Object(O.r)({maxId:e,onlyMedia:i}))})),t}Object(d.a)(t,e);var n=t.prototype;return n.componentDidMount=function(){var e=this.props,t=e.dispatch,n=e.onlyMedia;t(Object(O.r)({onlyMedia:n})),this.disconnect=t(Object(C.a)({onlyMedia:n}))},n.componentDidUpdate=function(e){if(e.onlyMedia!==this.props.onlyMedia){var t=this.props,n=t.dispatch,o=t.onlyMedia;this.disconnect(),n(Object(O.r)({onlyMedia:o})),this.disconnect=n(Object(C.a)({onlyMedia:o}))}},n.componentWillUnmount=function(){this.disconnect&&(this.disconnect(),this.disconnect=null)},n.render=function(){var e=this.props,t=e.intl,n=e.shouldUpdateScroll,o=e.hasUnread,i=e.columnId,c=e.multiColumn,l=e.onlyMedia,d=!!i;return u.a.createElement(y.a,{bindToDocument:!c,ref:this.setRef,label:t.formatMessage(w.title)},Object(a.a)(j.a,{icon:"users",active:o,title:t.formatMessage(w.title),onPin:this.handlePin,onMove:this.handleMove,onClick:this.handleHeaderClick,pinned:d,multiColumn:c},void 0,Object(a.a)(I,{columnId:i})),Object(a.a)(f.a,{trackScroll:!d,scrollKey:"community_timeline-"+i,timelineId:"community"+(l?":media":""),onLoadMore:this.handleLoadMore,emptyMessage:Object(a.a)(p.b,{id:"empty_column.community",defaultMessage:"The local timeline is empty. Write something publicly to get the ball rolling!"}),shouldUpdateScroll:n,bindToDocument:!c}))},t}(u.a.PureComponent),Object(r.a)(i,"contextTypes",{router:b.a.object}),Object(r.a)(i,"defaultProps",{onlyMedia:!1}),o=c))||o)||o}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[19],{861:function(e,t,n){"use strict";n.r(t),n.d(t,"default",(function(){return U}));var o,i,c,a=n(0),l=n(2),d=(n(9),n(6),n(8)),r=n(1),s=n(3),u=n.n(s),m=n(15),p=n(7),h=n(5),b=n.n(h),f=n(1063),y=n(762),j=n(759),O=n(36),M=n(253),g=n(1172),v=n(74),I=Object(m.connect)((function(e,t){var n=t.columnId,o=e.getIn(["settings","columns"]),i=o.findIndex((function(e){return e.get("uuid")===n}));return{settings:n&&i>=0?o.get(i).get("params"):e.getIn(["settings","community"])}}),(function(e,t){var n=t.columnId;return{onChange:function(t,o){e(n?Object(M.f)(n,t,o):Object(v.c)(["community"].concat(t),o))}}}))(g.a),C=n(766);var w=Object(p.f)({title:{id:"column.community",defaultMessage:"Local timeline"}}),U=Object(m.connect)((function(e,t){var n=t.columnId,o=n,i=e.getIn(["settings","columns"]),c=i.findIndex((function(e){return e.get("uuid")===o})),a=n&&c>=0?i.get(c).getIn(["params","other","onlyMedia"]):e.getIn(["settings","community","other","onlyMedia"]),l=e.getIn(["timelines","community"+(a?":media":"")]);return{hasUnread:!!l&&l.get("unread")>0,onlyMedia:a}}))(o=Object(p.g)((c=i=function(e){Object(d.a)(n,e);var t;t=n;function n(){for(var t,n=arguments.length,o=new Array(n),i=0;i<n;i++)o[i]=arguments[i];return t=e.call.apply(e,[this].concat(o))||this,Object(r.a)(Object(l.a)(t),"handlePin",(function(){var e=t.props,n=e.columnId,o=e.dispatch,i=e.onlyMedia;o(n?Object(M.h)(n):Object(M.e)("COMMUNITY",{other:{onlyMedia:i}}))})),Object(r.a)(Object(l.a)(t),"handleMove",(function(e){var n=t.props,o=n.columnId;(0,n.dispatch)(Object(M.g)(o,e))})),Object(r.a)(Object(l.a)(t),"handleHeaderClick",(function(){t.column.scrollTop()})),Object(r.a)(Object(l.a)(t),"setRef",(function(e){t.column=e})),Object(r.a)(Object(l.a)(t),"handleLoadMore",(function(e){var n=t.props,o=n.dispatch,i=n.onlyMedia;o(Object(O.r)({maxId:e,onlyMedia:i}))})),t}var o=n.prototype;return o.componentDidMount=function(){var e=this.props,t=e.dispatch,n=e.onlyMedia;t(Object(O.r)({onlyMedia:n})),this.disconnect=t(Object(C.a)({onlyMedia:n}))},o.componentDidUpdate=function(e){if(e.onlyMedia!==this.props.onlyMedia){var t=this.props,n=t.dispatch,o=t.onlyMedia;this.disconnect(),n(Object(O.r)({onlyMedia:o})),this.disconnect=n(Object(C.a)({onlyMedia:o}))}},o.componentWillUnmount=function(){this.disconnect&&(this.disconnect(),this.disconnect=null)},o.render=function(){var e=this.props,t=e.intl,n=e.shouldUpdateScroll,o=e.hasUnread,i=e.columnId,c=e.multiColumn,l=e.onlyMedia,d=!!i;return u.a.createElement(y.a,{bindToDocument:!c,ref:this.setRef,label:t.formatMessage(w.title)},Object(a.a)(j.a,{icon:"users",active:o,title:t.formatMessage(w.title),onPin:this.handlePin,onMove:this.handleMove,onClick:this.handleHeaderClick,pinned:d,multiColumn:c},void 0,Object(a.a)(I,{columnId:i})),Object(a.a)(f.a,{trackScroll:!d,scrollKey:"community_timeline-"+i,timelineId:"community"+(l?":media":""),onLoadMore:this.handleLoadMore,emptyMessage:Object(a.a)(p.b,{id:"empty_column.community",defaultMessage:"The local timeline is empty. Write something publicly to get the ball rolling!"}),shouldUpdateScroll:n,bindToDocument:!c}))},n}(u.a.PureComponent),Object(r.a)(i,"contextTypes",{router:b.a.object}),Object(r.a)(i,"defaultProps",{onlyMedia:!1}),o=c))||o)||o}}]);
//# sourceMappingURL=community_timeline.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[23],{826:function(n,e,o){"use strict";o.r(e);var a,t,i,c,r,s,d=o(0),l=o(2),u=o(7),m=o(1),b=o(62),f=o.n(b),p=(o(3),o(13)),j=o(6),O=o(18),h=o(5),g=o.n(h),k=o(14),v=o.n(k),M=o(300),y=o(731),_=o(737),D=o(80),w=o(50),U=Object(j.f)({unblockDomain:{id:"account.unblock_domain",defaultMessage:"Unhide {domain}"}}),C=Object(j.g)((i=t=function(n){function e(){for(var e,o=arguments.length,a=new Array(o),t=0;t<o;t++)a[t]=arguments[t];return e=n.call.apply(n,[this].concat(a))||this,Object(m.a)(Object(l.a)(e),"handleDomainUnblock",(function(){e.props.onUnblockDomain(e.props.domain)})),e}return Object(u.a)(e,n),e.prototype.render=function(){var n=this.props,e=n.domain,o=n.intl;return Object(d.a)("div",{className:"domain"},void 0,Object(d.a)("div",{className:"domain__wrapper"},void 0,Object(d.a)("span",{className:"domain__domain-name"},void 0,Object(d.a)("strong",{},void 0,e)),Object(d.a)("div",{className:"domain__buttons"},void 0,Object(d.a)(w.a,{active:!0,icon:"unlock",title:o.formatMessage(U.unblockDomain,{domain:e}),onClick:this.handleDomainUnblock}))))},e}(O.a),Object(m.a)(t,"propTypes",{domain:g.a.string,onUnblockDomain:g.a.func.isRequired,intl:g.a.object.isRequired}),a=i))||a,R=o(47),q=Object(j.f)({blockDomainConfirm:{id:"confirmations.domain_block.confirm",defaultMessage:"Hide entire domain"}}),N=Object(j.g)(Object(p.connect)((function(){return function(){return{}}}),(function(n,e){var o=e.intl;return{onBlockDomain:function(e){n(Object(R.d)("CONFIRM",{message:Object(d.a)(j.b,{id:"confirmations.domain_block.message",defaultMessage:"Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",values:{domain:Object(d.a)("strong",{},void 0,e)}}),confirm:o.formatMessage(q.blockDomainConfirm),onConfirm:function(){return n(Object(D.e)(e))}}))},onUnblockDomain:function(e){n(Object(D.h)(e))}}}))(C)),T=o(1023);o.d(e,"default",(function(){return S}));var I=Object(j.f)({heading:{id:"column.domain_blocks",defaultMessage:"Hidden domains"},unblockDomain:{id:"account.unblock_domain",defaultMessage:"Unhide {domain}"}}),S=Object(p.connect)((function(n){return{domains:n.getIn(["domain_lists","blocks","items"]),hasMore:!!n.getIn(["domain_lists","blocks","next"])}}))(c=Object(j.g)((s=r=function(n){function e(){for(var e,o=arguments.length,a=new Array(o),t=0;t<o;t++)a[t]=arguments[t];return e=n.call.apply(n,[this].concat(a))||this,Object(m.a)(Object(l.a)(e),"handleLoadMore",f()((function(){e.props.dispatch(Object(D.f)())}),300,{leading:!0})),e}Object(u.a)(e,n);var o=e.prototype;return o.componentWillMount=function(){this.props.dispatch(Object(D.g)())},o.render=function(){var n=this.props,e=n.intl,o=n.domains,a=n.shouldUpdateScroll,t=n.hasMore,i=n.multiColumn;if(!o)return Object(d.a)(y.a,{},void 0,Object(d.a)(M.a,{}));var c=Object(d.a)(j.b,{id:"empty_column.domain_blocks",defaultMessage:"There are no hidden domains yet."});return Object(d.a)(y.a,{bindToDocument:!i,icon:"minus-circle",heading:e.formatMessage(I.heading)},void 0,Object(d.a)(_.a,{}),Object(d.a)(T.a,{scrollKey:"domain_blocks",onLoadMore:this.handleLoadMore,hasMore:t,shouldUpdateScroll:a,emptyMessage:c,bindToDocument:!i},void 0,o.map((function(n){return Object(d.a)(N,{domain:n},n)}))))},e}(O.a),Object(m.a)(r,"propTypes",{params:g.a.object.isRequired,dispatch:g.a.func.isRequired,shouldUpdateScroll:g.a.func,hasMore:g.a.bool,domains:v.a.orderedSet,intl:g.a.object.isRequired,multiColumn:g.a.bool}),c=s))||c)||c}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[23],{852:function(n,o,a){"use strict";a.r(o),a.d(o,"default",(function(){return S}));var e,t,i,c=a(0),r=a(2),s=(a(9),a(6),a(8)),d=a(1),l=a(65),u=a.n(l),m=(a(3),a(15)),b=a(7),f=a(21),p=a(5),j=a.n(p),O=a(16),h=a.n(O),k=a(306),g=a(757),v=a(763),M=a(84),y=a(53);var _,D,w,U=Object(b.f)({unblockDomain:{id:"account.unblock_domain",defaultMessage:"Unblock domain {domain}"}}),C=Object(b.g)((i=t=function(n){Object(s.a)(a,n);var o;o=a;function a(){for(var o,a=arguments.length,e=new Array(a),t=0;t<a;t++)e[t]=arguments[t];return o=n.call.apply(n,[this].concat(e))||this,Object(d.a)(Object(r.a)(o),"handleDomainUnblock",(function(){o.props.onUnblockDomain(o.props.domain)})),o}return a.prototype.render=function(){var n=this.props,o=n.domain,a=n.intl;return(Object(c.a)("div",{className:"domain"},void 0,Object(c.a)("div",{className:"domain__wrapper"},void 0,Object(c.a)("span",{className:"domain__domain-name"},void 0,Object(c.a)("strong",{},void 0,o)),Object(c.a)("div",{className:"domain__buttons"},void 0,Object(c.a)(y.a,{active:!0,icon:"unlock",title:a.formatMessage(U.unblockDomain,{domain:o}),onClick:this.handleDomainUnblock})))))},a}(f.a),Object(d.a)(t,"propTypes",{domain:j.a.string,onUnblockDomain:j.a.func.isRequired,intl:j.a.object.isRequired}),e=i))||e,R=a(48),q=Object(b.f)({blockDomainConfirm:{id:"confirmations.domain_block.confirm",defaultMessage:"Block entire domain"}}),N=Object(b.g)(Object(m.connect)((function(){return function(){return{}}}),(function(n,o){var a=o.intl;return{onBlockDomain:function(o){n(Object(R.d)("CONFIRM",{message:Object(c.a)(b.b,{id:"confirmations.domain_block.message",defaultMessage:"Are you really, really sure you want to block the entire {domain}? In most cases a few targeted blocks or mutes are sufficient and preferable.",values:{domain:Object(c.a)("strong",{},void 0,o)}}),confirm:a.formatMessage(q.blockDomainConfirm),onConfirm:function(){return n(Object(M.e)(o))}}))},onUnblockDomain:function(o){n(Object(M.h)(o))}}}))(C)),T=a(1049);var I=Object(b.f)({heading:{id:"column.domain_blocks",defaultMessage:"Blocked domains"},unblockDomain:{id:"account.unblock_domain",defaultMessage:"Unblock domain {domain}"}}),S=Object(m.connect)((function(n){return{domains:n.getIn(["domain_lists","blocks","items"]),hasMore:!!n.getIn(["domain_lists","blocks","next"])}}))(_=Object(b.g)((w=D=function(n){Object(s.a)(a,n);var o;o=a;function a(){for(var o,a=arguments.length,e=new Array(a),t=0;t<a;t++)e[t]=arguments[t];return o=n.call.apply(n,[this].concat(e))||this,Object(d.a)(Object(r.a)(o),"handleLoadMore",u()((function(){o.props.dispatch(Object(M.f)())}),300,{leading:!0})),o}var e=a.prototype;return e.componentWillMount=function(){this.props.dispatch(Object(M.g)())},e.render=function(){var n=this.props,o=n.intl,a=n.domains,e=n.shouldUpdateScroll,t=n.hasMore,i=n.multiColumn;if(!a)return Object(c.a)(g.a,{},void 0,Object(c.a)(k.a,{}));var r=Object(c.a)(b.b,{id:"empty_column.domain_blocks",defaultMessage:"There are no blocked domains yet."});return(Object(c.a)(g.a,{bindToDocument:!i,icon:"minus-circle",heading:o.formatMessage(I.heading)},void 0,Object(c.a)(v.a,{}),Object(c.a)(T.a,{scrollKey:"domain_blocks",onLoadMore:this.handleLoadMore,hasMore:t,shouldUpdateScroll:e,emptyMessage:r,bindToDocument:!i},void 0,a.map((function(n){return Object(c.a)(N,{domain:n},n)})))))},a}(f.a),Object(d.a)(D,"propTypes",{params:j.a.object.isRequired,dispatch:j.a.func.isRequired,shouldUpdateScroll:j.a.func,hasMore:j.a.bool,domains:h.a.orderedSet,intl:j.a.object.isRequired,multiColumn:j.a.bool}),_=w))||_)||_}}]);
//# sourceMappingURL=domain_blocks.js.map

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[24],{799:function(t,e,a){"use strict";a.r(e),a.d(e,"default",(function(){return C}));var o,n,s,i=a(0),c=a(2),u=a(7),l=a(1),r=a(62),d=a.n(r),h=a(3),p=a.n(h),b=a(13),f=a(5),j=a.n(f),O=a(14),m=a.n(O),g=a(204),v=a(731),M=a(733),I=a(250),w=a(1038),y=a(6),L=a(18),k=Object(y.f)({heading:{id:"column.favourites",defaultMessage:"Favourites"}}),C=Object(b.connect)((function(t){return{statusIds:t.getIn(["status_lists","favourites","items"]),isLoading:t.getIn(["status_lists","favourites","isLoading"],!0),hasMore:!!t.getIn(["status_lists","favourites","next"])}}))(o=Object(y.g)((s=n=function(t){function e(){for(var e,a=arguments.length,o=new Array(a),n=0;n<a;n++)o[n]=arguments[n];return e=t.call.apply(t,[this].concat(o))||this,Object(l.a)(Object(c.a)(e),"handlePin",(function(){var t=e.props,a=t.columnId,o=t.dispatch;o(a?Object(I.h)(a):Object(I.e)("FAVOURITES",{}))})),Object(l.a)(Object(c.a)(e),"handleMove",(function(t){var a=e.props,o=a.columnId;(0,a.dispatch)(Object(I.g)(o,t))})),Object(l.a)(Object(c.a)(e),"handleHeaderClick",(function(){e.column.scrollTop()})),Object(l.a)(Object(c.a)(e),"setRef",(function(t){e.column=t})),Object(l.a)(Object(c.a)(e),"handleLoadMore",d()((function(){e.props.dispatch(Object(g.g)())}),300,{leading:!0})),e}Object(u.a)(e,t);var a=e.prototype;return a.componentWillMount=function(){this.props.dispatch(Object(g.h)())},a.render=function(){var t=this.props,e=t.intl,a=t.shouldUpdateScroll,o=t.statusIds,n=t.columnId,s=t.multiColumn,c=t.hasMore,u=t.isLoading,l=!!n,r=Object(i.a)(y.b,{id:"empty_column.favourited_statuses",defaultMessage:"You don't have any favourite toots yet. When you favourite one, it will show up here."});return p.a.createElement(v.a,{bindToDocument:!s,ref:this.setRef,label:e.formatMessage(k.heading)},Object(i.a)(M.a,{icon:"star",title:e.formatMessage(k.heading),onPin:this.handlePin,onMove:this.handleMove,onClick:this.handleHeaderClick,pinned:l,multiColumn:s,showBackButton:!0}),Object(i.a)(w.a,{trackScroll:!l,statusIds:o,scrollKey:"favourited_statuses-"+n,hasMore:c,isLoading:u,onLoadMore:this.handleLoadMore,shouldUpdateScroll:a,emptyMessage:r,bindToDocument:!s}))},e}(L.a),Object(l.a)(n,"propTypes",{dispatch:j.a.func.isRequired,shouldUpdateScroll:j.a.func,statusIds:m.a.list.isRequired,intl:j.a.object.isRequired,columnId:j.a.string,multiColumn:j.a.bool,hasMore:j.a.bool,isLoading:j.a.bool}),o=s))||o)||o}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[24],{825:function(t,e,a){"use strict";a.r(e),a.d(e,"default",(function(){return C}));var o,n,s,i=a(0),c=a(2),u=(a(9),a(6),a(8)),r=a(1),l=a(65),d=a.n(l),h=a(3),p=a.n(h),b=a(15),f=a(5),j=a.n(f),O=a(16),m=a.n(O),g=a(208),v=a(757),M=a(759),I=a(253),w=a(1065),y=a(7),L=a(21);var k=Object(y.f)({heading:{id:"column.favourites",defaultMessage:"Favourites"}}),C=Object(b.connect)((function(t){return{statusIds:t.getIn(["status_lists","favourites","items"]),isLoading:t.getIn(["status_lists","favourites","isLoading"],!0),hasMore:!!t.getIn(["status_lists","favourites","next"])}}))(o=Object(y.g)((s=n=function(t){Object(u.a)(a,t);var e;e=a;function a(){for(var e,a=arguments.length,o=new Array(a),n=0;n<a;n++)o[n]=arguments[n];return e=t.call.apply(t,[this].concat(o))||this,Object(r.a)(Object(c.a)(e),"handlePin",(function(){var t=e.props,a=t.columnId,o=t.dispatch;o(a?Object(I.h)(a):Object(I.e)("FAVOURITES",{}))})),Object(r.a)(Object(c.a)(e),"handleMove",(function(t){var a=e.props,o=a.columnId;(0,a.dispatch)(Object(I.g)(o,t))})),Object(r.a)(Object(c.a)(e),"handleHeaderClick",(function(){e.column.scrollTop()})),Object(r.a)(Object(c.a)(e),"setRef",(function(t){e.column=t})),Object(r.a)(Object(c.a)(e),"handleLoadMore",d()((function(){e.props.dispatch(Object(g.g)())}),300,{leading:!0})),e}var o=a.prototype;return o.componentWillMount=function(){this.props.dispatch(Object(g.h)())},o.render=function(){var t=this.props,e=t.intl,a=t.shouldUpdateScroll,o=t.statusIds,n=t.columnId,s=t.multiColumn,c=t.hasMore,u=t.isLoading,r=!!n,l=Object(i.a)(y.b,{id:"empty_column.favourited_statuses",defaultMessage:"You don't have any favourite toots yet. When you favourite one, it will show up here."});return p.a.createElement(v.a,{bindToDocument:!s,ref:this.setRef,label:e.formatMessage(k.heading)},Object(i.a)(M.a,{icon:"star",title:e.formatMessage(k.heading),onPin:this.handlePin,onMove:this.handleMove,onClick:this.handleHeaderClick,pinned:r,multiColumn:s,showBackButton:!0}),Object(i.a)(w.a,{trackScroll:!r,statusIds:o,scrollKey:"favourited_statuses-"+n,hasMore:c,isLoading:u,onLoadMore:this.handleLoadMore,shouldUpdateScroll:a,emptyMessage:l,bindToDocument:!s}))},a}(L.a),Object(r.a)(n,"propTypes",{dispatch:j.a.func.isRequired,shouldUpdateScroll:j.a.func,statusIds:m.a.list.isRequired,intl:j.a.object.isRequired,columnId:j.a.string,multiColumn:j.a.bool,hasMore:j.a.bool,isLoading:j.a.bool}),o=s))||o)||o}}]);
//# sourceMappingURL=favourited_statuses.js.map

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[25],{797:function(t,e,a){"use strict";a.r(e),a.d(e,"default",(function(){return q}));var s,o,r,n=a(0),c=a(2),i=a(7),u=a(1),p=(a(3),a(13)),d=a(18),l=a(5),h=a.n(l),f=a(14),b=a.n(f),m=a(300),j=a(45),O=a(6),v=a(1026),I=a(731),w=a(1023),y=a(26),g=a(733),R=Object(O.f)({refresh:{id:"refresh",defaultMessage:"Refresh"}}),q=Object(p.connect)((function(t,e){return{accountIds:t.getIn(["user_lists","favourited_by",e.params.statusId])}}))(s=Object(O.g)((r=o=function(t){function e(){for(var e,a=arguments.length,s=new Array(a),o=0;o<a;o++)s[o]=arguments[o];return e=t.call.apply(t,[this].concat(s))||this,Object(u.a)(Object(c.a)(e),"handleRefresh",(function(){e.props.dispatch(Object(j.q)(e.props.params.statusId))})),e}Object(i.a)(e,t);var a=e.prototype;return a.componentWillMount=function(){this.props.accountIds||this.props.dispatch(Object(j.q)(this.props.params.statusId))},a.componentWillReceiveProps=function(t){t.params.statusId!==this.props.params.statusId&&t.params.statusId&&this.props.dispatch(Object(j.q)(t.params.statusId))},a.render=function(){var t=this.props,e=t.intl,a=t.shouldUpdateScroll,s=t.accountIds,o=t.multiColumn;if(!s)return Object(n.a)(I.a,{},void 0,Object(n.a)(m.a,{}));var r=Object(n.a)(O.b,{id:"empty_column.favourites",defaultMessage:"No one has favourited this toot yet. When someone does, they will show up here."});return Object(n.a)(I.a,{bindToDocument:!o},void 0,Object(n.a)(g.a,{showBackButton:!0,multiColumn:o,extraButton:Object(n.a)("button",{className:"column-header__button",title:e.formatMessage(R.refresh),"aria-label":e.formatMessage(R.refresh),onClick:this.handleRefresh},void 0,Object(n.a)(y.a,{id:"refresh"}))}),Object(n.a)(w.a,{scrollKey:"favourites",shouldUpdateScroll:a,emptyMessage:r,bindToDocument:!o},void 0,s.map((function(t){return Object(n.a)(v.a,{id:t,withNote:!1},t)}))))},e}(d.a),Object(u.a)(o,"propTypes",{params:h.a.object.isRequired,dispatch:h.a.func.isRequired,shouldUpdateScroll:h.a.func,accountIds:b.a.list,multiColumn:h.a.bool,intl:h.a.object.isRequired}),s=r))||s)||s}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[25],{823:function(t,e,a){"use strict";a.r(e),a.d(e,"default",(function(){return q}));var s,o,r,n=a(0),c=a(2),i=(a(9),a(6),a(8)),u=a(1),p=(a(3),a(15)),d=a(21),l=a(5),h=a.n(l),f=a(16),b=a.n(f),m=a(306),j=a(46),O=a(7),v=a(1053),I=a(757),w=a(1049),y=a(27),g=a(759);var R=Object(O.f)({refresh:{id:"refresh",defaultMessage:"Refresh"}}),q=Object(p.connect)((function(t,e){return{accountIds:t.getIn(["user_lists","favourited_by",e.params.statusId])}}))(s=Object(O.g)((r=o=function(t){Object(i.a)(a,t);var e;e=a;function a(){for(var e,a=arguments.length,s=new Array(a),o=0;o<a;o++)s[o]=arguments[o];return e=t.call.apply(t,[this].concat(s))||this,Object(u.a)(Object(c.a)(e),"handleRefresh",(function(){e.props.dispatch(Object(j.q)(e.props.params.statusId))})),e}var s=a.prototype;return s.componentWillMount=function(){this.props.accountIds||this.props.dispatch(Object(j.q)(this.props.params.statusId))},s.componentWillReceiveProps=function(t){t.params.statusId!==this.props.params.statusId&&t.params.statusId&&this.props.dispatch(Object(j.q)(t.params.statusId))},s.render=function(){var t=this.props,e=t.intl,a=t.shouldUpdateScroll,s=t.accountIds,o=t.multiColumn;if(!s)return Object(n.a)(I.a,{},void 0,Object(n.a)(m.a,{}));var r=Object(n.a)(O.b,{id:"empty_column.favourites",defaultMessage:"No one has favourited this toot yet. When someone does, they will show up here."});return(Object(n.a)(I.a,{bindToDocument:!o},void 0,Object(n.a)(g.a,{showBackButton:!0,multiColumn:o,extraButton:Object(n.a)("button",{className:"column-header__button",title:e.formatMessage(R.refresh),"aria-label":e.formatMessage(R.refresh),onClick:this.handleRefresh},void 0,Object(n.a)(y.a,{id:"refresh"}))}),Object(n.a)(w.a,{scrollKey:"favourites",shouldUpdateScroll:a,emptyMessage:r,bindToDocument:!o},void 0,s.map((function(t){return Object(n.a)(v.a,{id:t,withNote:!1},t)})))))},a}(d.a),Object(u.a)(o,"propTypes",{params:h.a.object.isRequired,dispatch:h.a.func.isRequired,shouldUpdateScroll:h.a.func,accountIds:b.a.list,multiColumn:h.a.bool,intl:h.a.object.isRequired}),s=r))||s)||s}}]);
//# sourceMappingURL=favourites.js.map

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[26],{825:function(e,t,a){"use strict";a.r(t);var o,c,n,i,r,s,u=a(0),l=a(2),d=a(7),b=a(1),j=a(62),p=a.n(j),f=(a(3),a(13)),h=a(6),O=a(18),m=a(5),v=a.n(m),_=a(14),g=a.n(_),w=a(300),M=a(731),q=a(737),y=a(206),z=a(294),R=a(111),N=a(118),I=a(50),k=Object(h.f)({authorize:{id:"follow_request.authorize",defaultMessage:"Authorize"},reject:{id:"follow_request.reject",defaultMessage:"Reject"}}),A=Object(h.g)((n=c=function(e){function t(){return e.apply(this,arguments)||this}return Object(d.a)(t,e),t.prototype.render=function(){var e=this.props,t=e.intl,a=e.account,o=e.onAuthorize,c=e.onReject,n={__html:a.get("note_emojified")};return Object(u.a)("div",{className:"account-authorize__wrapper"},void 0,Object(u.a)("div",{className:"account-authorize"},void 0,Object(u.a)(z.a,{href:a.get("url"),to:"/accounts/"+a.get("id"),className:"detailed-status__display-name"},void 0,Object(u.a)("div",{className:"account-authorize__avatar"},void 0,Object(u.a)(R.a,{account:a,size:48})),Object(u.a)(N.a,{account:a})),Object(u.a)("div",{className:"account__header__content",dangerouslySetInnerHTML:n})),Object(u.a)("div",{className:"account--panel"},void 0,Object(u.a)("div",{className:"account--panel__button"},void 0,Object(u.a)(I.a,{title:t.formatMessage(k.authorize),icon:"check",onClick:o})),Object(u.a)("div",{className:"account--panel__button"},void 0,Object(u.a)(I.a,{title:t.formatMessage(k.reject),icon:"times",onClick:c}))))},t}(O.a),Object(b.a)(c,"propTypes",{account:g.a.map.isRequired,onAuthorize:v.a.func.isRequired,onReject:v.a.func.isRequired,intl:v.a.object.isRequired}),o=n))||o,T=a(25),C=Object(f.connect)((function(){var e=Object(y.d)();return function(t,a){return{account:e(t,a.id)}}}),(function(e,t){var a=t.id;return{onAuthorize:function(){e(Object(T.v)(a))},onReject:function(){e(Object(T.I)(a))}}}))(A),L=a(1023);a.d(t,"default",(function(){return U}));var S=Object(h.f)({heading:{id:"column.follow_requests",defaultMessage:"Follow requests"}}),U=Object(f.connect)((function(e){return{accountIds:e.getIn(["user_lists","follow_requests","items"]),hasMore:!!e.getIn(["user_lists","follow_requests","next"])}}))(i=Object(h.g)((s=r=function(e){function t(){for(var t,a=arguments.length,o=new Array(a),c=0;c<a;c++)o[c]=arguments[c];return t=e.call.apply(e,[this].concat(o))||this,Object(b.a)(Object(l.a)(t),"handleLoadMore",p()((function(){t.props.dispatch(Object(T.x)())}),300,{leading:!0})),t}Object(d.a)(t,e);var a=t.prototype;return a.componentWillMount=function(){this.props.dispatch(Object(T.B)())},a.render=function(){var e=this.props,t=e.intl,a=e.shouldUpdateScroll,o=e.accountIds,c=e.hasMore,n=e.multiColumn;if(!o)return Object(u.a)(M.a,{},void 0,Object(u.a)(w.a,{}));var i=Object(u.a)(h.b,{id:"empty_column.follow_requests",defaultMessage:"You don't have any follow requests yet. When you receive one, it will show up here."});return Object(u.a)(M.a,{bindToDocument:!n,icon:"user-plus",heading:t.formatMessage(S.heading)},void 0,Object(u.a)(q.a,{}),Object(u.a)(L.a,{scrollKey:"follow_requests",onLoadMore:this.handleLoadMore,hasMore:c,shouldUpdateScroll:a,emptyMessage:i,bindToDocument:!n},void 0,o.map((function(e){return Object(u.a)(C,{id:e},e)}))))},t}(O.a),Object(b.a)(r,"propTypes",{params:v.a.object.isRequired,dispatch:v.a.func.isRequired,shouldUpdateScroll:v.a.func,hasMore:v.a.bool,accountIds:g.a.list,intl:v.a.object.isRequired,multiColumn:v.a.bool}),i=s))||i)||i}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[26],{851:function(e,t,a){"use strict";a.r(t),a.d(t,"default",(function(){return U}));var o,n,c,i=a(0),s=a(2),u=(a(9),a(6),a(8)),r=a(1),l=a(65),d=a.n(l),b=(a(3),a(15)),p=a(7),f=a(21),h=a(5),j=a.n(h),m=a(16),v=a.n(m),O=a(306),_=a(757),g=a(763),w=a(210),q=a(300),y=a(115),M=a(122),k=a(53);var z,R,I,N=Object(p.f)({authorize:{id:"follow_request.authorize",defaultMessage:"Authorize"},reject:{id:"follow_request.reject",defaultMessage:"Reject"}}),A=Object(p.g)((c=n=function(e){Object(u.a)(a,e);var t;t=a;function a(){return e.apply(this,arguments)||this}return a.prototype.render=function(){var e=this.props,t=e.intl,a=e.account,o=e.onAuthorize,n=e.onReject,c={__html:a.get("note_emojified")};return Object(i.a)("div",{className:"account-authorize__wrapper"},void 0,Object(i.a)("div",{className:"account-authorize"},void 0,Object(i.a)(q.a,{href:a.get("url"),to:"/accounts/"+a.get("id"),className:"detailed-status__display-name"},void 0,Object(i.a)("div",{className:"account-authorize__avatar"},void 0,Object(i.a)(y.a,{account:a,size:48})),Object(i.a)(M.a,{account:a})),Object(i.a)("div",{className:"account__header__content",dangerouslySetInnerHTML:c})),Object(i.a)("div",{className:"account--panel"},void 0,Object(i.a)("div",{className:"account--panel__button"},void 0,Object(i.a)(k.a,{title:t.formatMessage(N.authorize),icon:"check",onClick:o})),Object(i.a)("div",{className:"account--panel__button"},void 0,Object(i.a)(k.a,{title:t.formatMessage(N.reject),icon:"times",onClick:n}))))},a}(f.a),Object(r.a)(n,"propTypes",{account:v.a.map.isRequired,onAuthorize:j.a.func.isRequired,onReject:j.a.func.isRequired,intl:j.a.object.isRequired}),o=c))||o,T=a(26),x=Object(b.connect)((function(){var e=Object(w.d)();return function(t,a){return{account:e(t,a.id)}}}),(function(e,t){var a=t.id;return{onAuthorize:function(){e(Object(T.v)(a))},onReject:function(){e(Object(T.I)(a))}}}))(A),C=a(1049),L=a(22);var S=Object(p.f)({heading:{id:"column.follow_requests",defaultMessage:"Follow requests"}}),U=Object(b.connect)((function(e){return{accountIds:e.getIn(["user_lists","follow_requests","items"]),hasMore:!!e.getIn(["user_lists","follow_requests","next"]),locked:!!e.getIn(["accounts",L.n,"locked"]),domain:e.getIn(["meta","domain"])}}))(z=Object(p.g)((I=R=function(e){Object(u.a)(a,e);var t;t=a;function a(){for(var t,a=arguments.length,o=new Array(a),n=0;n<a;n++)o[n]=arguments[n];return t=e.call.apply(e,[this].concat(o))||this,Object(r.a)(Object(s.a)(t),"handleLoadMore",d()((function(){t.props.dispatch(Object(T.x)())}),300,{leading:!0})),t}var o=a.prototype;return o.componentWillMount=function(){this.props.dispatch(Object(T.B)())},o.render=function(){var e=this.props,t=e.intl,a=e.shouldUpdateScroll,o=e.accountIds,n=e.hasMore,c=e.multiColumn,s=e.locked,u=e.domain;if(!o)return Object(i.a)(_.a,{},void 0,Object(i.a)(O.a,{}));var r=Object(i.a)(p.b,{id:"empty_column.follow_requests",defaultMessage:"You don't have any follow requests yet. When you receive one, it will show up here."}),l=s?null:Object(i.a)("div",{className:"follow_requests-unlocked_explanation"},void 0,Object(i.a)(p.b,{id:"follow_requests.unlocked_explanation",defaultMessage:"Even though your account is not locked, the {domain} staff thought you might want to review follow requests from these accounts manually.",values:{domain:u}}));return Object(i.a)(_.a,{bindToDocument:!c,icon:"user-plus",heading:t.formatMessage(S.heading)},void 0,Object(i.a)(g.a,{}),Object(i.a)(C.a,{scrollKey:"follow_requests",onLoadMore:this.handleLoadMore,hasMore:n,shouldUpdateScroll:a,emptyMessage:r,bindToDocument:!c,prepend:l},void 0,o.map((function(e){return Object(i.a)(x,{id:e},e)}))))},a}(f.a),Object(r.a)(R,"propTypes",{params:j.a.object.isRequired,dispatch:j.a.func.isRequired,shouldUpdateScroll:j.a.func,hasMore:j.a.bool,accountIds:v.a.list,locked:j.a.bool,domain:j.a.string,intl:j.a.object.isRequired,multiColumn:j.a.bool}),z=I))||z)||z}}]);
//# sourceMappingURL=follow_requests.js.map

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[27],{794:function(a,t,o){"use strict";o.r(t),o.d(t,"default",(function(){return C}));var c,e,s,n=o(0),r=o(2),p=o(7),i=o(1),u=o(62),d=o.n(u),l=(o(3),o(13)),b=o(18),h=o(5),m=o.n(h),f=o(14),j=o.n(f),I=o(300),O=o(25),y=o(6),w=o(1026),v=o(731),M=o(1057),g=o(738),k=o(1023),A=o(1030),C=Object(l.connect)((function(a,t){return{isAccount:!!a.getIn(["accounts",t.params.accountId]),accountIds:a.getIn(["user_lists","followers",t.params.accountId,"items"]),hasMore:!!a.getIn(["user_lists","followers",t.params.accountId,"next"]),blockedBy:a.getIn(["relationships",t.params.accountId,"blocked_by"],!1)}}))((s=e=function(a){function t(){for(var t,o=arguments.length,c=new Array(o),e=0;e<o;e++)c[e]=arguments[e];return t=a.call.apply(a,[this].concat(c))||this,Object(i.a)(Object(r.a)(t),"handleLoadMore",d()((function(){t.props.dispatch(Object(O.y)(t.props.params.accountId))}),300,{leading:!0})),t}Object(p.a)(t,a);var o=t.prototype;return o.componentWillMount=function(){this.props.accountIds||(this.props.dispatch(Object(O.A)(this.props.params.accountId)),this.props.dispatch(Object(O.C)(this.props.params.accountId)))},o.componentWillReceiveProps=function(a){a.params.accountId!==this.props.params.accountId&&a.params.accountId&&(this.props.dispatch(Object(O.A)(a.params.accountId)),this.props.dispatch(Object(O.C)(a.params.accountId)))},o.render=function(){var a=this.props,t=a.shouldUpdateScroll,o=a.accountIds,c=a.hasMore,e=a.blockedBy,s=a.isAccount,r=a.multiColumn;if(!s)return Object(n.a)(v.a,{},void 0,Object(n.a)(A.a,{}));if(!o)return Object(n.a)(v.a,{},void 0,Object(n.a)(I.a,{}));var p=e?Object(n.a)(y.b,{id:"empty_column.account_unavailable",defaultMessage:"Profile unavailable"}):Object(n.a)(y.b,{id:"account.followers.empty",defaultMessage:"No one follows this user yet."});return Object(n.a)(v.a,{},void 0,Object(n.a)(g.a,{multiColumn:r}),Object(n.a)(k.a,{scrollKey:"followers",hasMore:c,onLoadMore:this.handleLoadMore,shouldUpdateScroll:t,prepend:Object(n.a)(M.a,{accountId:this.props.params.accountId,hideTabs:!0}),alwaysPrepend:!0,emptyMessage:p,bindToDocument:!r},void 0,e?[]:o.map((function(a){return Object(n.a)(w.a,{id:a,withNote:!1},a)}))))},t}(b.a),Object(i.a)(e,"propTypes",{params:m.a.object.isRequired,dispatch:m.a.func.isRequired,shouldUpdateScroll:m.a.func,accountIds:j.a.list,hasMore:m.a.bool,blockedBy:m.a.bool,isAccount:m.a.bool,multiColumn:m.a.bool}),c=s))||c}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[27],{820:function(a,t,o){"use strict";o.r(t),o.d(t,"default",(function(){return C}));var c,e,s,n=o(0),r=o(2),p=(o(9),o(6),o(8)),i=o(1),u=o(65),d=o.n(u),l=(o(3),o(15)),b=o(21),h=o(5),m=o.n(h),f=o(16),j=o.n(f),I=o(306),O=o(26),y=o(7),v=o(1053),w=o(757),M=o(1084),g=o(764),k=o(1049),A=o(1057);var C=Object(l.connect)((function(a,t){return{isAccount:!!a.getIn(["accounts",t.params.accountId]),accountIds:a.getIn(["user_lists","followers",t.params.accountId,"items"]),hasMore:!!a.getIn(["user_lists","followers",t.params.accountId,"next"]),blockedBy:a.getIn(["relationships",t.params.accountId,"blocked_by"],!1)}}))((s=e=function(a){Object(p.a)(o,a);var t;t=o;function o(){for(var t,o=arguments.length,c=new Array(o),e=0;e<o;e++)c[e]=arguments[e];return t=a.call.apply(a,[this].concat(c))||this,Object(i.a)(Object(r.a)(t),"handleLoadMore",d()((function(){t.props.dispatch(Object(O.y)(t.props.params.accountId))}),300,{leading:!0})),t}var c=o.prototype;return c.componentWillMount=function(){this.props.accountIds||(this.props.dispatch(Object(O.A)(this.props.params.accountId)),this.props.dispatch(Object(O.C)(this.props.params.accountId)))},c.componentWillReceiveProps=function(a){a.params.accountId!==this.props.params.accountId&&a.params.accountId&&(this.props.dispatch(Object(O.A)(a.params.accountId)),this.props.dispatch(Object(O.C)(a.params.accountId)))},c.render=function(){var a=this.props,t=a.shouldUpdateScroll,o=a.accountIds,c=a.hasMore,e=a.blockedBy,s=a.isAccount,r=a.multiColumn;if(!s)return Object(n.a)(w.a,{},void 0,Object(n.a)(A.a,{}));if(!o)return Object(n.a)(w.a,{},void 0,Object(n.a)(I.a,{}));var p=e?Object(n.a)(y.b,{id:"empty_column.account_unavailable",defaultMessage:"Profile unavailable"}):Object(n.a)(y.b,{id:"account.followers.empty",defaultMessage:"No one follows this user yet."});return(Object(n.a)(w.a,{},void 0,Object(n.a)(g.a,{multiColumn:r}),Object(n.a)(k.a,{scrollKey:"followers",hasMore:c,onLoadMore:this.handleLoadMore,shouldUpdateScroll:t,prepend:Object(n.a)(M.a,{accountId:this.props.params.accountId,hideTabs:!0}),alwaysPrepend:!0,emptyMessage:p,bindToDocument:!r},void 0,e?[]:o.map((function(a){return Object(n.a)(v.a,{id:a,withNote:!1},a)})))))},o}(b.a),Object(i.a)(e,"propTypes",{params:m.a.object.isRequired,dispatch:m.a.func.isRequired,shouldUpdateScroll:m.a.func,accountIds:j.a.list,hasMore:m.a.bool,blockedBy:m.a.bool,isAccount:m.a.bool,multiColumn:m.a.bool}),c=s))||c}}]);
//# sourceMappingURL=followers.js.map

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[28],{795:function(a,t,o){"use strict";o.r(t),o.d(t,"default",(function(){return _}));var c,e,n,s=o(0),r=o(2),i=o(7),p=o(1),u=o(62),d=o.n(u),l=(o(3),o(13)),b=o(18),h=o(5),m=o.n(h),f=o(14),j=o.n(f),I=o(300),O=o(25),y=o(6),w=o(1026),g=o(731),v=o(1057),M=o(738),k=o(1023),A=o(1030),_=Object(l.connect)((function(a,t){return{isAccount:!!a.getIn(["accounts",t.params.accountId]),accountIds:a.getIn(["user_lists","following",t.params.accountId,"items"]),hasMore:!!a.getIn(["user_lists","following",t.params.accountId,"next"]),blockedBy:a.getIn(["relationships",t.params.accountId,"blocked_by"],!1)}}))((n=e=function(a){function t(){for(var t,o=arguments.length,c=new Array(o),e=0;e<o;e++)c[e]=arguments[e];return t=a.call.apply(a,[this].concat(c))||this,Object(p.a)(Object(r.a)(t),"handleLoadMore",d()((function(){t.props.dispatch(Object(O.z)(t.props.params.accountId))}),300,{leading:!0})),t}Object(i.a)(t,a);var o=t.prototype;return o.componentWillMount=function(){this.props.accountIds||(this.props.dispatch(Object(O.A)(this.props.params.accountId)),this.props.dispatch(Object(O.D)(this.props.params.accountId)))},o.componentWillReceiveProps=function(a){a.params.accountId!==this.props.params.accountId&&a.params.accountId&&(this.props.dispatch(Object(O.A)(a.params.accountId)),this.props.dispatch(Object(O.D)(a.params.accountId)))},o.render=function(){var a=this.props,t=a.shouldUpdateScroll,o=a.accountIds,c=a.hasMore,e=a.blockedBy,n=a.isAccount,r=a.multiColumn;if(!n)return Object(s.a)(g.a,{},void 0,Object(s.a)(A.a,{}));if(!o)return Object(s.a)(g.a,{},void 0,Object(s.a)(I.a,{}));var i=e?Object(s.a)(y.b,{id:"empty_column.account_unavailable",defaultMessage:"Profile unavailable"}):Object(s.a)(y.b,{id:"account.follows.empty",defaultMessage:"This user doesn't follow anyone yet."});return Object(s.a)(g.a,{},void 0,Object(s.a)(M.a,{multiColumn:r}),Object(s.a)(k.a,{scrollKey:"following",hasMore:c,onLoadMore:this.handleLoadMore,shouldUpdateScroll:t,prepend:Object(s.a)(v.a,{accountId:this.props.params.accountId,hideTabs:!0}),alwaysPrepend:!0,emptyMessage:i,bindToDocument:!r},void 0,e?[]:o.map((function(a){return Object(s.a)(w.a,{id:a,withNote:!1},a)}))))},t}(b.a),Object(p.a)(e,"propTypes",{params:m.a.object.isRequired,dispatch:m.a.func.isRequired,shouldUpdateScroll:m.a.func,accountIds:j.a.list,hasMore:m.a.bool,blockedBy:m.a.bool,isAccount:m.a.bool,multiColumn:m.a.bool}),c=n))||c}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[28],{821:function(a,t,o){"use strict";o.r(t),o.d(t,"default",(function(){return _}));var c,e,n,s=o(0),r=o(2),i=(o(9),o(6),o(8)),p=o(1),u=o(65),d=o.n(u),l=(o(3),o(15)),b=o(21),h=o(5),m=o.n(h),f=o(16),j=o.n(f),I=o(306),O=o(26),y=o(7),v=o(1053),w=o(757),g=o(1084),M=o(764),k=o(1049),A=o(1057);var _=Object(l.connect)((function(a,t){return{isAccount:!!a.getIn(["accounts",t.params.accountId]),accountIds:a.getIn(["user_lists","following",t.params.accountId,"items"]),hasMore:!!a.getIn(["user_lists","following",t.params.accountId,"next"]),blockedBy:a.getIn(["relationships",t.params.accountId,"blocked_by"],!1)}}))((n=e=function(a){Object(i.a)(o,a);var t;t=o;function o(){for(var t,o=arguments.length,c=new Array(o),e=0;e<o;e++)c[e]=arguments[e];return t=a.call.apply(a,[this].concat(c))||this,Object(p.a)(Object(r.a)(t),"handleLoadMore",d()((function(){t.props.dispatch(Object(O.z)(t.props.params.accountId))}),300,{leading:!0})),t}var c=o.prototype;return c.componentWillMount=function(){this.props.accountIds||(this.props.dispatch(Object(O.A)(this.props.params.accountId)),this.props.dispatch(Object(O.D)(this.props.params.accountId)))},c.componentWillReceiveProps=function(a){a.params.accountId!==this.props.params.accountId&&a.params.accountId&&(this.props.dispatch(Object(O.A)(a.params.accountId)),this.props.dispatch(Object(O.D)(a.params.accountId)))},c.render=function(){var a=this.props,t=a.shouldUpdateScroll,o=a.accountIds,c=a.hasMore,e=a.blockedBy,n=a.isAccount,r=a.multiColumn;if(!n)return Object(s.a)(w.a,{},void 0,Object(s.a)(A.a,{}));if(!o)return Object(s.a)(w.a,{},void 0,Object(s.a)(I.a,{}));var i=e?Object(s.a)(y.b,{id:"empty_column.account_unavailable",defaultMessage:"Profile unavailable"}):Object(s.a)(y.b,{id:"account.follows.empty",defaultMessage:"This user doesn't follow anyone yet."});return(Object(s.a)(w.a,{},void 0,Object(s.a)(M.a,{multiColumn:r}),Object(s.a)(k.a,{scrollKey:"following",hasMore:c,onLoadMore:this.handleLoadMore,shouldUpdateScroll:t,prepend:Object(s.a)(g.a,{accountId:this.props.params.accountId,hideTabs:!0}),alwaysPrepend:!0,emptyMessage:i,bindToDocument:!r},void 0,e?[]:o.map((function(a){return Object(s.a)(v.a,{id:a,withNote:!1},a)})))))},o}(b.a),Object(p.a)(e,"propTypes",{params:m.a.object.isRequired,dispatch:m.a.func.isRequired,shouldUpdateScroll:m.a.func,accountIds:j.a.list,hasMore:m.a.bool,blockedBy:m.a.bool,isAccount:m.a.bool,multiColumn:m.a.bool}),c=n))||c}}]);
//# sourceMappingURL=following.js.map

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[29],{798:function(a,n,e){"use strict";e.r(n);var t=e(0),c=(e(3),e(731)),o=e(1030);n.default=function(){return Object(t.a)(c.a,{},void 0,Object(t.a)(o.a,{fullPage:!0}))}}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[29],{824:function(a,n,e){"use strict";e.r(n);var t=e(0),c=(e(3),e(757)),o=e(1057);n.default=function(){return Object(t.a)(c.a,{},void 0,Object(t.a)(o.a,{fullPage:!0}))}}}]);
//# sourceMappingURL=generic_not_found.js.map

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -1,2 +1,2 @@
(window.webpackJsonp=window.webpackJsonp||[]).push([[32],{821:function(t,e,n){"use strict";n.r(e);var i,a,c,o,s,r,d,u,l,p=n(0),b=n(7),f=n(1),v=(n(3),n(5)),j=n.n(v),O=n(14),m=n.n(O),_=n(13),R=n(18),g=n(6),I=n(28),h=n(54),N=n(39),q=n(23),y=Object(g.f)({remove:{id:"lists.account.remove",defaultMessage:"Remove from list"},add:{id:"lists.account.add",defaultMessage:"Add to list"}}),w=Object(_.connect)((function(t,e){var n=e.listId,i=e.added;return{list:t.get("lists").get(n),added:void 0===i?t.getIn(["listAdder","lists","items"]).includes(n):i}}),(function(t,e){var n=e.listId;return{onRemove:function(){return t(Object(I.J)(n))},onAdd:function(){return t(Object(I.A)(n))}}}))(i=Object(g.g)((c=a=function(t){function e(){return t.apply(this,arguments)||this}return Object(b.a)(e,t),e.prototype.render=function(){var t,e=this.props,n=e.list,i=e.intl,a=e.onRemove,c=e.onAdd;return t=e.added?Object(p.a)(N.a,{icon:"times",title:i.formatMessage(y.remove),onClick:a}):Object(p.a)(N.a,{icon:"plus",title:i.formatMessage(y.add),onClick:c}),Object(p.a)("div",{className:"list"},void 0,Object(p.a)("div",{className:"list__wrapper"},void 0,Object(p.a)("div",{className:"list__display-name"},void 0,Object(p.a)(q.a,{id:"list-ul",className:"column-link__icon",fixedWidth:!0}),n.get("title")),Object(p.a)("div",{className:"account__relationship"},void 0,t)))},e}(R.a),Object(f.a)(a,"propTypes",{list:m.a.map.isRequired,intl:j.a.object.isRequired,onRemove:j.a.func.isRequired,onAdd:j.a.func.isRequired,added:j.a.bool}),Object(f.a)(a,"defaultProps",{added:!1}),i=c))||i)||i,A=n(103),k=n(91),M=n(93),z=Object(_.connect)((function(){var t=Object(A.d)();return function(e,n){var i=n.accountId;return{account:t(e,i)}}}))(o=Object(g.g)((r=s=function(t){function e(){return t.apply(this,arguments)||this}return Object(b.a)(e,t),e.prototype.render=function(){var t=this.props.account;return Object(p.a)("div",{className:"account"},void 0,Object(p.a)("div",{className:"account__wrapper"},void 0,Object(p.a)("div",{className:"account__display-name"},void 0,Object(p.a)("div",{className:"account__avatar-wrapper"},void 0,Object(p.a)(k.a,{account:t,size:36})),Object(p.a)(M.a,{account:t}))))},e}(R.a),Object(f.a)(s,"propTypes",{account:m.a.map.isRequired}),o=r))||o)||o,C=n(1118);n.d(e,"default",(function(){return T}));var J=Object(h.a)([function(t){return t.get("lists")}],(function(t){return t?t.toList().filter((function(t){return!!t})).sort((function(t,e){return t.get("title").localeCompare(e.get("title"))})):t})),T=Object(_.connect)((function(t){return{listIds:J(t).map((function(t){return t.get("id")}))}}),(function(t){return{onInitialize:function(e){return t(Object(I.N)(e))},onReset:function(){return t(Object(I.L)())}}}))(d=Object(g.g)((l=u=function(t){function e(){return t.apply(this,arguments)||this}Object(b.a)(e,t);var n=e.prototype;return n.componentDidMount=function(){var t=this.props;(0,t.onInitialize)(t.accountId)},n.componentWillUnmount=function(){(0,this.props.onReset)()},n.render=function(){var t=this.props,e=t.accountId,n=t.listIds;return Object(p.a)("div",{className:"modal-root__modal list-adder"},void 0,Object(p.a)("div",{className:"list-adder__account"},void 0,Object(p.a)(z,{accountId:e})),Object(p.a)(C.a,{}),Object(p.a)("div",{className:"list-adder__lists"},void 0,n.map((function(t){return Object(p.a)(w,{listId:t},t)}))))},e}(R.a),Object(f.a)(u,"propTypes",{accountId:j.a.string.isRequired,onClose:j.a.func.isRequired,intl:j.a.object.isRequired,onInitialize:j.a.func.isRequired,onReset:j.a.func.isRequired,listIds:m.a.list.isRequired}),d=l))||d)||d}}]);
(window.webpackJsonp=window.webpackJsonp||[]).push([[32],{848:function(t,e,n){"use strict";n.r(e),n.d(e,"default",(function(){return T}));var i,a,c,o=n(0),r=(n(9),n(6),n(8)),s=n(1),d=(n(3),n(5)),u=n.n(d),l=n(16),p=n.n(l),v=n(15),b=n(21),f=n(7),j=n(30),O=n(57),m=n(41),_=n(25);var R,g,I,h=Object(f.f)({remove:{id:"lists.account.remove",defaultMessage:"Remove from list"},add:{id:"lists.account.add",defaultMessage:"Add to list"}}),N=Object(v.connect)((function(t,e){var n=e.listId,i=e.added;return{list:t.get("lists").get(n),added:void 0===i?t.getIn(["listAdder","lists","items"]).includes(n):i}}),(function(t,e){var n=e.listId;return{onRemove:function(){return t(Object(j.J)(n))},onAdd:function(){return t(Object(j.A)(n))}}}))(i=Object(f.g)((c=a=function(t){Object(r.a)(n,t);var e;e=n;function n(){return t.apply(this,arguments)||this}return n.prototype.render=function(){var t,e=this.props,n=e.list,i=e.intl,a=e.onRemove,c=e.onAdd;return t=e.added?Object(o.a)(m.a,{icon:"times",title:i.formatMessage(h.remove),onClick:a}):Object(o.a)(m.a,{icon:"plus",title:i.formatMessage(h.add),onClick:c}),Object(o.a)("div",{className:"list"},void 0,Object(o.a)("div",{className:"list__wrapper"},void 0,Object(o.a)("div",{className:"list__display-name"},void 0,Object(o.a)(_.a,{id:"list-ul",className:"column-link__icon",fixedWidth:!0}),n.get("title")),Object(o.a)("div",{className:"account__relationship"},void 0,t)))},n}(b.a),Object(s.a)(a,"propTypes",{list:p.a.map.isRequired,intl:u.a.object.isRequired,onRemove:u.a.func.isRequired,onAdd:u.a.func.isRequired,added:u.a.bool}),Object(s.a)(a,"defaultProps",{added:!1}),i=c))||i)||i,q=n(108),y=n(96),w=n(98);var A,k,M,z=Object(v.connect)((function(){var t=Object(q.d)();return function(e,n){var i=n.accountId;return{account:t(e,i)}}}))(R=Object(f.g)((I=g=function(t){Object(r.a)(n,t);var e;e=n;function n(){return t.apply(this,arguments)||this}return n.prototype.render=function(){var t=this.props.account;return(Object(o.a)("div",{className:"account"},void 0,Object(o.a)("div",{className:"account__wrapper"},void 0,Object(o.a)("div",{className:"account__display-name"},void 0,Object(o.a)("div",{className:"account__avatar-wrapper"},void 0,Object(o.a)(y.a,{account:t,size:36})),Object(o.a)(w.a,{account:t})))))},n}(b.a),Object(s.a)(g,"propTypes",{account:p.a.map.isRequired}),R=I))||R)||R,C=n(1150);var J=Object(O.a)([function(t){return t.get("lists")}],(function(t){return t?t.toList().filter((function(t){return!!t})).sort((function(t,e){return t.get("title").localeCompare(e.get("title"))})):t})),T=Object(v.connect)((function(t){return{listIds:J(t).map((function(t){return t.get("id")}))}}),(function(t){return{onInitialize:function(e){return t(Object(j.N)(e))},onReset:function(){return t(Object(j.L)())}}}))(A=Object(f.g)((M=k=function(t){Object(r.a)(n,t);var e;e=n;function n(){return t.apply(this,arguments)||this}var i=n.prototype;return i.componentDidMount=function(){var t=this.props;(0,t.onInitialize)(t.accountId)},i.componentWillUnmount=function(){(0,this.props.onReset)()},i.render=function(){var t=this.props,e=t.accountId,n=t.listIds;return(Object(o.a)("div",{className:"modal-root__modal list-adder"},void 0,Object(o.a)("div",{className:"list-adder__account"},void 0,Object(o.a)(z,{accountId:e})),Object(o.a)(C.a,{}),Object(o.a)("div",{className:"list-adder__lists"},void 0,n.map((function(t){return Object(o.a)(N,{listId:t},t)})))))},n}(b.a),Object(s.a)(k,"propTypes",{accountId:u.a.string.isRequired,onClose:u.a.func.isRequired,intl:u.a.object.isRequired,onInitialize:u.a.func.isRequired,onReset:u.a.func.isRequired,listIds:p.a.list.isRequired}),A=M))||A)||A}}]);
//# sourceMappingURL=list_adder.js.map

File diff suppressed because one or more lines are too long

Some files were not shown because too many files have changed in this diff Show More