diff --git a/README.md b/README.md index 664b8b475..fcf296c01 100644 --- a/README.md +++ b/README.md @@ -22,7 +22,7 @@ No release has been made yet, but several servers have been online for months al ### Dependencies * Postgresql version 9.6 or newer -* Elixir version 1.4 or newer (you will also need erlang-dev, erlang-parsetools, erlang-xmerl packages) +* Elixir version 1.5 or newer * Build-essential tools ### Configuration @@ -50,3 +50,12 @@ Logs can be watched by using `journalctl -fu pleroma.service` ### Standalone/run by other means Run `mix phx.server` in repository's root, it will output log into stdout/stderr + +### Using an upstream proxy for federation + +Add the following to your `dev.secret.exs` or `prod.secret.exs` if you want to proxify all http requests that pleroma makes to an upstream proxy server: + + config :pleroma, :http, + proxy_url: "127.0.0.1:8123" + +This is useful for running pleroma inside Tor or i2p. diff --git a/config/config.exs b/config/config.exs index f26f9ecdf..e6c695215 100644 --- a/config/config.exs +++ b/config/config.exs @@ -33,7 +33,7 @@ config :pleroma, :websub, Pleroma.Web.Websub config :pleroma, :ostatus, Pleroma.Web.OStatus -config :pleroma, :httpoison, HTTPoison +config :pleroma, :httpoison, Pleroma.HTTP version = with {version, 0} <- System.cmd("git", ["rev-parse", "HEAD"]) do "Pleroma #{String.trim(version)}" @@ -41,6 +41,10 @@ _ -> "Pleroma dev" end +# Configures http settings, upstream proxy etc. +config :pleroma, :http, + proxy_url: nil + config :pleroma, :instance, version: version, name: "Pleroma", @@ -48,6 +52,14 @@ limit: 5000, registrations_open: true +config :pleroma, :media_proxy, + enabled: false, + redirect_on_failure: true + #base_url: "https://cache.pleroma.social" + +config :pleroma, :chat, + enabled: true + # Import environment specific config. This must remain at the bottom # of this file so it overrides the configuration defined above. import_config "#{Mix.env}.exs" diff --git a/config/emoji.txt b/config/emoji.txt index 0e668e609..7afacb09f 100644 --- a/config/emoji.txt +++ b/config/emoji.txt @@ -1 +1,31 @@ firefox, /emoji/Firefox.gif +blank, /emoji/blank.png +f_00b, /emoji/f_00b.png +f_00b11b, /emoji/f_00b11b.png +f_00b33b, /emoji/f_00b33b.png +f_00h, /emoji/f_00h.png +f_00t, /emoji/f_00t.png +f_01b, /emoji/f_01b.png +f_03b, /emoji/f_03b.png +f_10b, /emoji/f_10b.png +f_11b, /emoji/f_11b.png +f_11b00b, /emoji/f_11b00b.png +f_11b22b, /emoji/f_11b22b.png +f_11h, /emoji/f_11h.png +f_11t, /emoji/f_11t.png +f_12b, /emoji/f_12b.png +f_21b, /emoji/f_21b.png +f_22b, /emoji/f_22b.png +f_22b11b, /emoji/f_22b11b.png +f_22b33b, /emoji/f_22b33b.png +f_22h, /emoji/f_22h.png +f_22t, /emoji/f_22t.png +f_23b, /emoji/f_23b.png +f_30b, /emoji/f_30b.png +f_32b, /emoji/f_32b.png +f_33b, /emoji/f_33b.png +f_33b00b, /emoji/f_33b00b.png +f_33b22b, /emoji/f_33b22b.png +f_33h, /emoji/f_33h.png +f_33t, /emoji/f_33t.png + diff --git a/config/prod.exs b/config/prod.exs index 732bab2b0..8522c67da 100644 --- a/config/prod.exs +++ b/config/prod.exs @@ -14,9 +14,12 @@ # manifest is generated by the mix phoenix.digest task # which you typically run after static files are built. config :pleroma, Pleroma.Web.Endpoint, - on_init: {Pleroma.Web.Endpoint, :load_from_system_env, []}, - url: [host: "example.com", port: 80], - cache_static_manifest: "priv/static/cache_manifest.json" + http: [port: 4000], + protocol: "http", + debug_errors: true, + code_reloader: true, + check_origin: false, + watchers: [] # Do not print debug messages in production config :logger, level: :info diff --git a/installation/Caddyfile b/installation/Caddyfile new file mode 100644 index 000000000..08d5e6169 --- /dev/null +++ b/installation/Caddyfile @@ -0,0 +1,5 @@ +instance.example.com { # Your instance's domain + proxy / localhost:4000 { + websocket + } +} diff --git a/installation/pleroma.nginx b/installation/pleroma.nginx index 6cf9f3fa0..f714792da 100644 --- a/installation/pleroma.nginx +++ b/installation/pleroma.nginx @@ -1,3 +1,6 @@ +proxy_cache_path /tmp/pleroma-media-cache levels=1:2 keys_zone=pleroma_media_cache:10m max_size=10g + inactive=720m use_temp_path=off; + server { listen 80; server_name example.tld; @@ -19,11 +22,17 @@ server { server_name example.tld; location / { + add_header 'Access-Control-Allow-Origin' '*'; proxy_http_version 1.1; proxy_set_header Upgrade $http_upgrade; proxy_set_header Connection "upgrade"; proxy_pass http://localhost:4000; } - include snippets/well-known.conf; -} \ No newline at end of file + location /proxy { + proxy_cache pleroma_media_cache; + proxy_cache_lock on; + proxy_pass http://localhost:4000; + } + +} diff --git a/lib/mix/tasks/generate_config.ex b/lib/mix/tasks/generate_config.ex index f20f93e4d..2d962124f 100644 --- a/lib/mix/tasks/generate_config.ex +++ b/lib/mix/tasks/generate_config.ex @@ -8,11 +8,20 @@ def run(_) do domain = IO.gets("What is your domain name? (e.g. pleroma.soykaf.com): ") |> String.trim name = IO.gets("What is the name of your instance? (e.g. Pleroma/Soykaf): ") |> String.trim email = IO.gets("What's your admin email address: ") |> String.trim + mediaproxy = IO.gets("Do you want to activate the mediaproxy? (y/N): ") + |> String.trim() + |> String.downcase() + |> String.starts_with?("y") + proxy_url = if mediaproxy do + IO.gets("What is the mediaproxy's URL? (e.g. https://cache.example.com): ") |> String.trim + else + "https://cache.example.com" + end secret = :crypto.strong_rand_bytes(64) |> Base.encode64 |> binary_part(0, 64) dbpass = :crypto.strong_rand_bytes(64) |> Base.encode64 |> binary_part(0, 64) resultSql = EEx.eval_file("lib/mix/tasks/sample_psql.eex", [dbpass: dbpass]) - result = EEx.eval_file("lib/mix/tasks/sample_config.eex", [domain: domain, email: email, name: name, secret: secret, dbpass: dbpass]) + result = EEx.eval_file("lib/mix/tasks/sample_config.eex", [domain: domain, email: email, name: name, secret: secret, mediaproxy: mediaproxy, proxy_url: proxy_url, dbpass: dbpass]) IO.puts("\nWriting config to config/generated_config.exs.\n\nCheck it and configure your database, then copy it to either config/dev.secret.exs or config/prod.secret.exs") File.write("config/generated_config.exs", result) diff --git a/lib/mix/tasks/sample_config.eex b/lib/mix/tasks/sample_config.eex index 85a7c554e..9330fae2d 100644 --- a/lib/mix/tasks/sample_config.eex +++ b/lib/mix/tasks/sample_config.eex @@ -10,6 +10,11 @@ config :pleroma, :instance, limit: 5000, registrations_open: true +config :pleroma, :media_proxy, + enabled: <%= mediaproxy %>, + redirect_on_failure: true, + base_url: "<%= proxy_url %>" + # Configure your database config :pleroma, Pleroma.Repo, adapter: Ecto.Adapters.Postgres, diff --git a/lib/pleroma/application.ex b/lib/pleroma/application.ex index 2969ca3c4..79b9dee9d 100644 --- a/lib/pleroma/application.ex +++ b/lib/pleroma/application.ex @@ -20,13 +20,18 @@ def start(_type, _args) do limit: 2500 ]]), worker(Pleroma.Web.Federator, []), - worker(Pleroma.Web.ChatChannel.ChatChannelState, []), + worker(Pleroma.Stats, []), ] ++ if Mix.env == :test, do: [], else: [worker(Pleroma.Web.Streamer, [])] + ++ if !chat_enabled(), do: [], else: [worker(Pleroma.Web.ChatChannel.ChatChannelState, [])] # See http://elixir-lang.org/docs/stable/elixir/Supervisor.html # for other strategies and supported options opts = [strategy: :one_for_one, name: Pleroma.Supervisor] Supervisor.start_link(children, opts) end + + defp chat_enabled do + Application.get_env(:pleroma, :chat, []) |> Keyword.get(:enabled) + end end diff --git a/lib/pleroma/formatter.ex b/lib/pleroma/formatter.ex index c98db2d94..fdf91f56e 100644 --- a/lib/pleroma/formatter.ex +++ b/lib/pleroma/formatter.ex @@ -1,5 +1,6 @@ defmodule Pleroma.Formatter do alias Pleroma.User + alias Pleroma.Web.MediaProxy @link_regex ~r/https?:\/\/[\w\.\/?=\-#%&@~\(\)]+[\w\/]/u def linkify(text) do @@ -10,7 +11,7 @@ def linkify(text) do def parse_tags(text, data \\ %{}) do Regex.scan(@tag_regex, text) |> Enum.map(fn (["#" <> tag = full_tag]) -> {full_tag, String.downcase(tag)} end) - |> (fn map -> if data["sensitive"], do: [{"#nsfw", "nsfw"}] ++ map, else: map end).() + |> (fn map -> if data["sensitive"] in [true, "True", "true", "1"], do: [{"#nsfw", "nsfw"}] ++ map, else: map end).() end def parse_mentions(text) do @@ -103,13 +104,19 @@ def html_escape(text) do {finmoji, "/finmoji/128px/#{finmoji}-128.png"} end) - @emoji_from_file (with {:ok, file} <- File.read("config/emoji.txt") do - file - |> String.trim - |> String.split("\n") - |> Enum.map(fn(line) -> - [name, file] = String.split(line, ", ") - {name, file} + @emoji_from_file (with {:ok, default} <- File.read("config/emoji.txt") do + custom = + with {:ok, custom} <- File.read("config/custom_emoji.txt") do + custom + else + _e -> "" + end + (default <> "\n" <> custom) + |> String.trim() + |> String.split(~r/\n+/) + |> Enum.map(fn(line) -> + [name, file] = String.split(line, ~r/,\s*/) + {name, file} end) else _ -> [] @@ -125,7 +132,7 @@ def emojify(text, additional \\ nil) do end Enum.reduce(all_emoji, text, fn ({emoji, file}, text) -> - String.replace(text, ":#{emoji}:", "#{emoji}") + String.replace(text, ":#{emoji}:", "#{emoji}") end) end diff --git a/lib/pleroma/http/http.ex b/lib/pleroma/http/http.ex new file mode 100644 index 000000000..8b8a82353 --- /dev/null +++ b/lib/pleroma/http/http.ex @@ -0,0 +1,14 @@ + +defmodule Pleroma.HTTP do + use HTTPoison.Base + + def process_request_options(options) do + config = Application.get_env(:pleroma, :http, []) + proxy = Keyword.get(config, :proxy_url, nil) + case proxy do + nil -> options + _ -> options ++ [proxy: proxy] + end + end + +end diff --git a/lib/pleroma/stats.ex b/lib/pleroma/stats.ex new file mode 100644 index 000000000..737e9b62e --- /dev/null +++ b/lib/pleroma/stats.ex @@ -0,0 +1,41 @@ +defmodule Pleroma.Stats do + import Ecto.Query + alias Pleroma.{User, Repo, Activity} + + def start_link do + agent = Agent.start_link(fn -> {[], %{}} end, name: __MODULE__) + spawn(fn -> schedule_update() end) + agent + end + + def get_stats do + Agent.get(__MODULE__, fn {_, stats} -> stats end) + end + + def get_peers do + Agent.get(__MODULE__, fn {peers, _} -> peers end) + end + + def schedule_update do + spawn(fn -> + Process.sleep(1000 * 60 * 60 * 1) # 1 hour + schedule_update() + end) + update_stats() + end + + def update_stats do + peers = from(u in Pleroma.User, + select: fragment("distinct ?->'host'", u.info), + where: u.local != ^true) + |> Repo.all() + domain_count = Enum.count(peers) + status_query = from(u in User.local_user_query, + select: fragment("sum((?->>'note_count')::int)", u.info)) + status_count = Repo.one(status_query) |> IO.inspect + user_count = Repo.aggregate(User.local_user_query, :count, :id) + Agent.update(__MODULE__, fn _ -> + {peers, %{domain_count: domain_count, status_count: status_count, user_count: user_count}} + end) + end +end diff --git a/lib/pleroma/upload.ex b/lib/pleroma/upload.ex index 3567c6c88..c41617c68 100644 --- a/lib/pleroma/upload.ex +++ b/lib/pleroma/upload.ex @@ -9,7 +9,7 @@ def store(%Plug.Upload{} = file) do File.cp!(file.path, result_file) # fix content type on some image uploads - content_type = if file.content_type == "application/octet-stream" do + content_type = if file.content_type in [nil, "application/octet-stream"] do get_content_type(file.path) else file.content_type diff --git a/lib/pleroma/user.ex b/lib/pleroma/user.ex index 4580f30fb..e544d3772 100644 --- a/lib/pleroma/user.ex +++ b/lib/pleroma/user.ex @@ -29,14 +29,14 @@ defmodule Pleroma.User do def avatar_url(user) do case user.avatar do %{"url" => [%{"href" => href} | _]} -> href - _ -> "https://placehold.it/48x48" + _ -> "#{Web.base_url()}/images/avi.png" end end def banner_url(user) do case user.info["banner"] do %{"url" => [%{"href" => href} | _]} -> href - _ -> nil + _ -> "#{Web.base_url()}/images/banner.png" end end diff --git a/lib/pleroma/web/channels/user_socket.ex b/lib/pleroma/web/channels/user_socket.ex index 4a9bb8e22..f18b3cb80 100644 --- a/lib/pleroma/web/channels/user_socket.ex +++ b/lib/pleroma/web/channels/user_socket.ex @@ -5,7 +5,9 @@ defmodule Pleroma.Web.UserSocket do ## Channels # channel "room:*", Pleroma.Web.RoomChannel - channel "chat:*", Pleroma.Web.ChatChannel + if Application.get_env(:pleroma, :chat) |> Keyword.get(:enabled) do + channel "chat:*", Pleroma.Web.ChatChannel + end ## Transports transport :websocket, Phoenix.Transports.WebSocket diff --git a/lib/pleroma/web/chat_channel.ex b/lib/pleroma/web/chat_channel.ex index 268bef17d..48a3553bf 100644 --- a/lib/pleroma/web/chat_channel.ex +++ b/lib/pleroma/web/chat_channel.ex @@ -24,7 +24,6 @@ def handle_in("new_msg", %{"text" => text}, %{assigns: %{user_name: user_name}} end defmodule Pleroma.Web.ChatChannel.ChatChannelState do - use Agent @max_messages 20 def start_link do diff --git a/lib/pleroma/web/common_api/utils.ex b/lib/pleroma/web/common_api/utils.ex index e60dff7dc..2b359dd72 100644 --- a/lib/pleroma/web/common_api/utils.ex +++ b/lib/pleroma/web/common_api/utils.ex @@ -95,7 +95,7 @@ def add_user_links(text, mentions) do Enum.reduce(mentions, step_one, fn ({match, %User{ap_id: ap_id}, uuid}, text) -> short_match = String.split(match, "@") |> tl() |> hd() - String.replace(text, uuid, "@#{short_match}") + String.replace(text, uuid, "@#{short_match}") end) end diff --git a/lib/pleroma/web/endpoint.ex b/lib/pleroma/web/endpoint.ex index b57cf3917..93b37dc74 100644 --- a/lib/pleroma/web/endpoint.ex +++ b/lib/pleroma/web/endpoint.ex @@ -1,7 +1,9 @@ defmodule Pleroma.Web.Endpoint do use Phoenix.Endpoint, otp_app: :pleroma - socket "/socket", Pleroma.Web.UserSocket + if Application.get_env(:pleroma, :chat) |> Keyword.get(:enabled) do + socket "/socket", Pleroma.Web.UserSocket + end socket "/api/v1", Pleroma.Web.MastodonAPI.MastodonSocket # Serve at "/" the static files from "priv/static" directory. @@ -12,7 +14,7 @@ defmodule Pleroma.Web.Endpoint do at: "/media", from: "uploads", gzip: false plug Plug.Static, at: "/", from: :pleroma, - only: ~w(index.html static finmoji emoji packs sounds sw.js) + only: ~w(index.html static finmoji emoji packs sounds images instance sw.js) # Code reloading can be explicitly enabled under the # :code_reloader configuration of your endpoint. diff --git a/lib/pleroma/web/federator/federator.ex b/lib/pleroma/web/federator/federator.ex index b23ed5fcc..c9f9dc7a1 100644 --- a/lib/pleroma/web/federator/federator.ex +++ b/lib/pleroma/web/federator/federator.ex @@ -41,12 +41,12 @@ def handle(:request_subscription, websub) do def handle(:publish, activity) do Logger.debug(fn -> "Running publish for #{activity.data["id"]}" end) with actor when not is_nil(actor) <- User.get_cached_by_ap_id(activity.data["actor"]) do - Logger.debug(fn -> "Sending #{activity.data["id"]} out via websub" end) - Websub.publish(Pleroma.Web.OStatus.feed_path(actor), actor, activity) - {:ok, actor} = WebFinger.ensure_keys_present(actor) Logger.debug(fn -> "Sending #{activity.data["id"]} out via salmon" end) Pleroma.Web.Salmon.publish(actor, activity) + + Logger.debug(fn -> "Sending #{activity.data["id"]} out via websub" end) + Websub.publish(Pleroma.Web.OStatus.feed_path(actor), actor, activity) end end diff --git a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex index e50f53ba4..e16a2a092 100644 --- a/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex +++ b/lib/pleroma/web/mastodon_api/mastodon_api_controller.ex @@ -1,6 +1,6 @@ defmodule Pleroma.Web.MastodonAPI.MastodonAPIController do use Pleroma.Web, :controller - alias Pleroma.{Repo, Activity, User, Notification} + alias Pleroma.{Repo, Activity, User, Notification, Stats} alias Pleroma.Web alias Pleroma.Web.MastodonAPI.{StatusView, AccountView, MastodonView} alias Pleroma.Web.ActivityPub.ActivityPub @@ -93,7 +93,6 @@ def user(conn, %{"id" => id}) do @instance Application.get_env(:pleroma, :instance) def masto_instance(conn, _params) do - user_count = Repo.aggregate(User.local_user_query, :count, :id) response = %{ uri: Web.base_url, title: Keyword.get(@instance, :name), @@ -103,17 +102,18 @@ def masto_instance(conn, _params) do urls: %{ streaming_api: String.replace(Web.base_url, ["http","https"], "wss") }, - stats: %{ - status_count: 2, - user_count: user_count, - domain_count: 3 - }, + stats: Stats.get_stats, + thumbnail: Web.base_url <> "/instance/thumbnail.jpeg", max_toot_chars: Keyword.get(@instance, :limit) } json(conn, response) end + def peers(conn, _params) do + json(conn, Stats.get_peers) + end + defp mastodonized_emoji do Pleroma.Formatter.get_custom_emoji() |> Enum.map(fn {shortcode, relative_url} -> @@ -162,7 +162,7 @@ def home_timeline(%{assigns: %{user: user}} = conn, params) do def public_timeline(%{assigns: %{user: user}} = conn, params) do params = params |> Map.put("type", ["Create", "Announce"]) - |> Map.put("local_only", !!params["local"]) + |> Map.put("local_only", params["local"] in [true, "True", "true", "1"]) |> Map.put("blocking_user", user) activities = ActivityPub.fetch_public_activities(params) diff --git a/lib/pleroma/web/mastodon_api/views/account_view.ex b/lib/pleroma/web/mastodon_api/views/account_view.ex index 02f1e60bb..d2a4dd366 100644 --- a/lib/pleroma/web/mastodon_api/views/account_view.ex +++ b/lib/pleroma/web/mastodon_api/views/account_view.ex @@ -3,20 +3,17 @@ defmodule Pleroma.Web.MastodonAPI.AccountView do alias Pleroma.User alias Pleroma.Web.MastodonAPI.AccountView alias Pleroma.Web.CommonAPI.Utils - - defp image_url(%{"url" => [ %{ "href" => href } | _ ]}), do: href - defp image_url(_), do: nil + alias Pleroma.Web.MediaProxy def render("accounts.json", %{users: users} = opts) do render_many(users, AccountView, "account.json", opts) end def render("account.json", %{user: user}) do - image = User.avatar_url(user) + image = User.avatar_url(user) |> MediaProxy.url() + header = User.banner_url(user) |> MediaProxy.url() user_info = User.user_info(user) - header = image_url(user.info["banner"]) || "https://placehold.it/700x335" - %{ id: to_string(user.id), username: hd(String.split(user.nickname, "@")), diff --git a/lib/pleroma/web/mastodon_api/views/status_view.ex b/lib/pleroma/web/mastodon_api/views/status_view.ex index 5585a5605..64f315597 100644 --- a/lib/pleroma/web/mastodon_api/views/status_view.ex +++ b/lib/pleroma/web/mastodon_api/views/status_view.ex @@ -3,6 +3,7 @@ defmodule Pleroma.Web.MastodonAPI.StatusView do alias Pleroma.Web.MastodonAPI.{AccountView, StatusView} alias Pleroma.{User, Activity} alias Pleroma.Web.CommonAPI.Utils + alias Pleroma.Web.MediaProxy def render("index.json", opts) do render_many(opts.activities, StatusView, "status.json", opts) @@ -121,9 +122,9 @@ def render("attachment.json", %{attachment: attachment}) do %{ id: to_string(attachment["id"] || hash_id), - url: href, + url: MediaProxy.url(href), remote_url: href, - preview_url: href, + preview_url: MediaProxy.url(href), text_url: href, type: type } diff --git a/lib/pleroma/web/media_proxy/controller.ex b/lib/pleroma/web/media_proxy/controller.ex new file mode 100644 index 000000000..9327e7253 --- /dev/null +++ b/lib/pleroma/web/media_proxy/controller.ex @@ -0,0 +1,84 @@ +defmodule Pleroma.Web.MediaProxy.MediaProxyController do + use Pleroma.Web, :controller + require Logger + + @httpoison Application.get_env(:pleroma, :httpoison) + + @max_body_length 25 * 1048576 + + @cache_control %{ + default: "public, max-age=1209600", + error: "public, must-revalidate, max-age=160", + } + + def remote(conn, %{"sig" => sig, "url" => url}) do + config = Application.get_env(:pleroma, :media_proxy, []) + with \ + true <- Keyword.get(config, :enabled, false), + {:ok, url} <- Pleroma.Web.MediaProxy.decode_url(sig, url), + {:ok, content_type, body} <- proxy_request(url) + do + conn + |> put_resp_content_type(content_type) + |> set_cache_header(:default) + |> send_resp(200, body) + else + false -> send_error(conn, 404) + {:error, :invalid_signature} -> send_error(conn, 403) + {:error, {:http, _, url}} -> redirect_or_error(conn, url, Keyword.get(config, :redirect_on_failure, true)) + end + end + + defp proxy_request(link) do + headers = [{"user-agent", "Pleroma/MediaProxy; #{Pleroma.Web.base_url()} <#{Application.get_env(:pleroma, :instance)[:email]}>"}] + options = @httpoison.process_request_options([:insecure, {:follow_redirect, true}]) + with \ + {:ok, 200, headers, client} <- :hackney.request(:get, link, headers, "", options), + headers = Enum.into(headers, Map.new), + {:ok, body} <- proxy_request_body(client), + content_type <- proxy_request_content_type(headers, body) + do + {:ok, content_type, body} + else + {:ok, status, _, _} -> + Logger.warn "MediaProxy: request failed, status #{status}, link: #{link}" + {:error, {:http, :bad_status, link}} + {:error, error} -> + Logger.warn "MediaProxy: request failed, error #{inspect error}, link: #{link}" + {:error, {:http, error, link}} + end + end + + defp set_cache_header(conn, key) do + Plug.Conn.put_resp_header(conn, "cache-control", @cache_control[key]) + end + + defp redirect_or_error(conn, url, true), do: redirect(conn, external: url) + defp redirect_or_error(conn, url, _), do: send_error(conn, 502, "Media proxy error: " <> url) + + defp send_error(conn, code, body \\ "") do + conn + |> set_cache_header(:error) + |> send_resp(code, body) + end + + defp proxy_request_body(client), do: proxy_request_body(client, <<>>) + defp proxy_request_body(client, body) when byte_size(body) < @max_body_length do + case :hackney.stream_body(client) do + {:ok, data} -> proxy_request_body(client, <>) + :done -> {:ok, body} + {:error, reason} -> {:error, reason} + end + end + defp proxy_request_body(client, _) do + :hackney.close(client) + {:error, :body_too_large} + end + + # TODO: the body is passed here as well because some hosts do not provide a content-type. + # At some point we may want to use magic numbers to discover the content-type and reply a proper one. + defp proxy_request_content_type(headers, _body) do + headers["Content-Type"] || headers["content-type"] || "image/jpeg" + end + +end diff --git a/lib/pleroma/web/media_proxy/media_proxy.ex b/lib/pleroma/web/media_proxy/media_proxy.ex new file mode 100644 index 000000000..23efc18fa --- /dev/null +++ b/lib/pleroma/web/media_proxy/media_proxy.ex @@ -0,0 +1,32 @@ +defmodule Pleroma.Web.MediaProxy do + @base64_opts [padding: false] + + def url(nil), do: nil + + def url(url = "/" <> _), do: url + + def url(url) do + config = Application.get_env(:pleroma, :media_proxy, []) + if !Keyword.get(config, :enabled, false) or String.starts_with?(url, Pleroma.Web.base_url) do + url + else + secret = Application.get_env(:pleroma, Pleroma.Web.Endpoint)[:secret_key_base] + base64 = Base.url_encode64(url, @base64_opts) + sig = :crypto.hmac(:sha, secret, base64) + sig64 = sig |> Base.url_encode64(@base64_opts) + Keyword.get(config, :base_url, Pleroma.Web.base_url) <> "/proxy/#{sig64}/#{base64}" + end + end + + def decode_url(sig, url) do + secret = Application.get_env(:pleroma, Pleroma.Web.Endpoint)[:secret_key_base] + sig = Base.url_decode64!(sig, @base64_opts) + local_sig = :crypto.hmac(:sha, secret, url) + if local_sig == sig do + {:ok, Base.url_decode64!(url, @base64_opts)} + else + {:error, :invalid_signature} + end + end + +end diff --git a/lib/pleroma/web/oauth/fallback_controller.ex b/lib/pleroma/web/oauth/fallback_controller.ex new file mode 100644 index 000000000..daa110532 --- /dev/null +++ b/lib/pleroma/web/oauth/fallback_controller.ex @@ -0,0 +1,12 @@ +defmodule Pleroma.Web.OAuth.FallbackController do + use Pleroma.Web, :controller + alias Pleroma.Web.OAuth.OAuthController + + # No user/password + def call(conn, _) do + conn + |> put_flash(:error, "Invalid Username/Password") + |> OAuthController.authorize(conn.params) + end + +end \ No newline at end of file diff --git a/lib/pleroma/web/oauth/oauth_controller.ex b/lib/pleroma/web/oauth/oauth_controller.ex index e8483dec0..94318bfa9 100644 --- a/lib/pleroma/web/oauth/oauth_controller.ex +++ b/lib/pleroma/web/oauth/oauth_controller.ex @@ -5,6 +5,11 @@ defmodule Pleroma.Web.OAuth.OAuthController do alias Pleroma.{Repo, User} alias Comeonin.Pbkdf2 + plug :fetch_session + plug :fetch_flash + + action_fallback Pleroma.Web.OAuth.FallbackController + def authorize(conn, params) do render conn, "show.html", %{ response_type: params["response_type"], diff --git a/lib/pleroma/web/ostatus/feed_representer.ex b/lib/pleroma/web/ostatus/feed_representer.ex index 08710f246..10860ce04 100644 --- a/lib/pleroma/web/ostatus/feed_representer.ex +++ b/lib/pleroma/web/ostatus/feed_representer.ex @@ -1,6 +1,8 @@ defmodule Pleroma.Web.OStatus.FeedRepresenter do alias Pleroma.Web.OStatus alias Pleroma.Web.OStatus.{UserRepresenter, ActivityRepresenter} + alias Pleroma.User + alias Pleroma.Web.MediaProxy def to_simple_form(user, activities, _users) do most_recent_update = (List.first(activities) || user).updated_at @@ -25,6 +27,7 @@ def to_simple_form(user, activities, _users) do {:id, h.(OStatus.feed_path(user))}, {:title, ['#{user.nickname}\'s timeline']}, {:updated, h.(most_recent_update)}, + {:logo, [to_charlist(User.avatar_url(user) |> MediaProxy.url())]}, {:link, [rel: 'hub', href: h.(OStatus.pubsub_path(user))], []}, {:link, [rel: 'salmon', href: h.(OStatus.salmon_path(user))], []}, {:link, [rel: 'self', href: h.(OStatus.feed_path(user)), type: 'application/atom+xml'], []}, diff --git a/lib/pleroma/web/ostatus/ostatus.ex b/lib/pleroma/web/ostatus/ostatus.ex index 745539b3e..c35ba42be 100644 --- a/lib/pleroma/web/ostatus/ostatus.ex +++ b/lib/pleroma/web/ostatus/ostatus.ex @@ -22,6 +22,10 @@ def salmon_path(user) do "#{user.ap_id}/salmon" end + def remote_follow_path do + "#{Web.base_url}/ostatus_subscribe?acct={uri}" + end + def handle_incoming(xml_string) do with doc when doc != :error <- parse_document(xml_string) do entries = :xmerl_xpath.string('//entry', doc) @@ -159,8 +163,7 @@ def get_content(entry) do Get the cw that mastodon uses. """ def get_cw(entry) do - with scope when not is_nil(scope) <- string_from_xpath("//mastodon:scope", entry), - cw when not is_nil(cw) <- string_from_xpath("/*/summary", entry) do + with cw when not is_nil(cw) <- string_from_xpath("/*/summary", entry) do cw else _e -> nil end diff --git a/lib/pleroma/web/router.ex b/lib/pleroma/web/router.ex index 4f9ebf5e8..6455ff108 100644 --- a/lib/pleroma/web/router.ex +++ b/lib/pleroma/web/router.ex @@ -28,6 +28,13 @@ def user_fetcher(username) do plug Pleroma.Plugs.AuthenticationPlug, %{fetcher: &Router.user_fetcher/1, optional: true} end + pipeline :pleroma_html do + plug :accepts, ["html"] + plug :fetch_session + plug Pleroma.Plugs.OAuthPlug + plug Pleroma.Plugs.AuthenticationPlug, %{fetcher: &Router.user_fetcher/1, optional: true} + end + pipeline :well_known do plug :accepts, ["xml", "xrd+xml"] end @@ -51,6 +58,18 @@ def user_fetcher(username) do get "/emoji", UtilController, :emoji end + scope "/", Pleroma.Web.TwitterAPI do + pipe_through :pleroma_html + get "/ostatus_subscribe", UtilController, :remote_follow + post "/ostatus_subscribe", UtilController, :do_remote_follow + post "/main/ostatus", UtilController, :remote_subscribe + end + + scope "/api/pleroma", Pleroma.Web.TwitterAPI do + pipe_through :authenticated_api + post "/follow_import", UtilController, :follow_import + end + scope "/oauth", Pleroma.Web.OAuth do get "/authorize", OAuthController, :authorize post "/authorize", OAuthController, :create_authorization @@ -101,6 +120,7 @@ def user_fetcher(username) do scope "/api/v1", Pleroma.Web.MastodonAPI do pipe_through :api get "/instance", MastodonAPIController, :masto_instance + get "/instance/peers", MastodonAPIController, :peers post "/apps", MastodonAPIController, :create_app get "/custom_emojis", MastodonAPIController, :custom_emojis @@ -142,6 +162,8 @@ def user_fetcher(username) do get "/qvitter/statuses/user_timeline", TwitterAPI.Controller, :user_timeline get "/users/show", TwitterAPI.Controller, :show_user + get "/statuses/followers", TwitterAPI.Controller, :followers + get "/statuses/friends", TwitterAPI.Controller, :friends get "/statuses/show/:id", TwitterAPI.Controller, :fetch_status get "/statusnet/conversation/:id", TwitterAPI.Controller, :fetch_conversation @@ -188,8 +210,6 @@ def user_fetcher(username) do post "/qvitter/update_avatar", TwitterAPI.Controller, :update_avatar - get "/statuses/followers", TwitterAPI.Controller, :followers - get "/statuses/friends", TwitterAPI.Controller, :friends get "/friends/ids", TwitterAPI.Controller, :friends_ids get "/friendships/no_retweets/ids", TwitterAPI.Controller, :empty_array @@ -243,6 +263,14 @@ def user_fetcher(username) do delete "/auth/sign_out", MastodonAPIController, :logout end + pipeline :remote_media do + plug :accepts, ["html"] + end + scope "/proxy/", Pleroma.Web.MediaProxy do + pipe_through :remote_media + get "/:sig/:url", MediaProxyController, :remote + end + scope "/", Fallback do get "/*path", RedirectController, :redirector end diff --git a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex index 3c6903a16..a7fa7523b 100644 --- a/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex +++ b/lib/pleroma/web/templates/o_auth/o_auth/show.html.eex @@ -1,3 +1,5 @@ + +

OAuth Authorization

<%= form_for @conn, o_auth_path(@conn, :authorize), [as: "authorization"], fn f -> %> <%= label f, :name, "Name" %> diff --git a/lib/pleroma/web/templates/twitter_api/util/follow.html.eex b/lib/pleroma/web/templates/twitter_api/util/follow.html.eex new file mode 100644 index 000000000..06359fa6c --- /dev/null +++ b/lib/pleroma/web/templates/twitter_api/util/follow.html.eex @@ -0,0 +1,11 @@ +<%= if @error == :error do %> +

Error fetching user

+<% else %> +

Remote follow

+ +

<%= @name %>

+ <%= form_for @conn, util_path(@conn, :do_remote_follow), [as: "user"], fn f -> %> + <%= hidden_input f, :id, value: @id %> + <%= submit "Authorize" %> + <% end %> +<% end %> diff --git a/lib/pleroma/web/templates/twitter_api/util/follow_login.html.eex b/lib/pleroma/web/templates/twitter_api/util/follow_login.html.eex new file mode 100644 index 000000000..4e3a2be67 --- /dev/null +++ b/lib/pleroma/web/templates/twitter_api/util/follow_login.html.eex @@ -0,0 +1,14 @@ +<%= if @error do %> +

<%= @error %>

+<% end %> +

Log in to follow

+

<%= @name %>

+ +<%= form_for @conn, util_path(@conn, :do_remote_follow), [as: "authorization"], fn f -> %> +<%= text_input f, :name, placeholder: "Username" %> +
+<%= password_input f, :password, placeholder: "Password" %> +
+<%= hidden_input f, :id, value: @id %> +<%= submit "Authorize" %> +<% end %> diff --git a/lib/pleroma/web/templates/twitter_api/util/followed.html.eex b/lib/pleroma/web/templates/twitter_api/util/followed.html.eex new file mode 100644 index 000000000..da473d502 --- /dev/null +++ b/lib/pleroma/web/templates/twitter_api/util/followed.html.eex @@ -0,0 +1,6 @@ +<%= if @error do %> +

Error following account

+<% else %> +

Account followed!

+<% end %> + diff --git a/lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex b/lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex new file mode 100644 index 000000000..f60accebf --- /dev/null +++ b/lib/pleroma/web/templates/twitter_api/util/subscribe.html.eex @@ -0,0 +1,10 @@ +<%= if @error do %> +

Error: <%= @error %>

+<% else %> +

Remotely follow <%= @nickname %>

+ <%= form_for @conn, util_path(@conn, :remote_subscribe), [as: "user"], fn f -> %> + <%= hidden_input f, :nickname, value: @nickname %> + <%= text_input f, :profile, placeholder: "Your account ID, e.g. lain@quitter.se" %> + <%= submit "Follow" %> + <% end %> +<% end %> diff --git a/lib/pleroma/web/twitter_api/controllers/util_controller.ex b/lib/pleroma/web/twitter_api/controllers/util_controller.ex index de2abd4d1..503719dbf 100644 --- a/lib/pleroma/web/twitter_api/controllers/util_controller.ex +++ b/lib/pleroma/web/twitter_api/controllers/util_controller.ex @@ -1,8 +1,12 @@ defmodule Pleroma.Web.TwitterAPI.UtilController do use Pleroma.Web, :controller + require Logger alias Pleroma.Web + alias Pleroma.Web.OStatus + alias Pleroma.Web.WebFinger + alias Comeonin.Pbkdf2 alias Pleroma.Formatter - + alias Pleroma.Web.ActivityPub.ActivityPub alias Pleroma.{Repo, PasswordResetToken, User} def show_password_reset(conn, %{"token" => token}) do @@ -29,6 +33,72 @@ def help_test(conn, _params) do json(conn, "ok") end + def remote_subscribe(conn, %{"nickname" => nick, "profile" => _}) do + with %User{} = user <- User.get_cached_by_nickname(nick), + avatar = User.avatar_url(user) do + conn + |> render("subscribe.html", %{nickname: nick, avatar: avatar, error: false}) + else + _e -> render(conn, "subscribe.html", %{nickname: nick, avatar: nil, error: "Could not find user"}) + end + end + def remote_subscribe(conn, %{"user" => %{"nickname" => nick, "profile" => profile}}) do + with {:ok, %{"subscribe_address" => template}} <- WebFinger.finger(profile), + %User{ap_id: ap_id} <- User.get_cached_by_nickname(nick) do + conn + |> Phoenix.Controller.redirect(external: String.replace(template, "{uri}", ap_id)) + else + _e -> + render(conn, "subscribe.html", %{nickname: nick, avatar: nil, error: "Something went wrong."}) + end + end + + def remote_follow(%{assigns: %{user: user}} = conn, %{"acct" => acct}) do + {err, followee} = OStatus.find_or_make_user(acct) + avatar = User.avatar_url(followee) + name = followee.nickname + id = followee.id + + if !!user do + conn + |> render("follow.html", %{error: err, acct: acct, avatar: avatar, name: name, id: id}) + else + conn + |> render("follow_login.html", %{error: false, acct: acct, avatar: avatar, name: name, id: id}) + end + end + + def do_remote_follow(conn, %{"authorization" => %{"name" => username, "password" => password, "id" => id}}) do + followee = Repo.get(User, id) + avatar = User.avatar_url(followee) + name = followee.nickname + with %User{} = user <- User.get_cached_by_nickname(username), + true <- Pbkdf2.checkpw(password, user.password_hash), + %User{} = followed <- Repo.get(User, id), + {:ok, follower} <- User.follow(user, followee), + {:ok, _activity} <- ActivityPub.follow(follower, followee) do + conn + |> render("followed.html", %{error: false}) + else + _e -> + conn + |> render("follow_login.html", %{error: "Wrong username or password", id: id, name: name, avatar: avatar}) + end + end + def do_remote_follow(%{assigns: %{user: user}} = conn, %{"user" => %{"id" => id}}) do + with %User{} = followee <- Repo.get(User, id), + {:ok, follower} <- User.follow(user, followee), + {:ok, _activity} <- ActivityPub.follow(follower, followee) do + conn + |> render("followed.html", %{error: false}) + else + e -> + Logger.debug("Remote follow failed with error #{inspect e}") + conn + |> render("followed.html", %{error: inspect(e)}) + end + end + @instance Application.get_env(:pleroma, :instance) def config(conn, _params) do case get_format(conn) do @@ -51,7 +121,7 @@ def config(conn, _params) do site: %{ name: Keyword.get(@instance, :name), server: Web.base_url, - textlimit: Keyword.get(@instance, :limit), + textlimit: to_string(Keyword.get(@instance, :limit)), closed: if(Keyword.get(@instance, :registrations_open), do: "0", else: "1") } }) @@ -73,4 +143,24 @@ def version(conn, _params) do def emoji(conn, _params) do json conn, Enum.into(Formatter.get_custom_emoji(), %{}) end + + def follow_import(conn, %{"list" => %Plug.Upload{} = listfile}) do + follow_import(conn, %{"list" => File.read!(listfile.path)}) + end + def follow_import(%{assigns: %{user: user}} = conn, %{"list" => list}) do + Task.start(fn -> + String.split(list) + |> Enum.map(fn nick -> + with %User{} = follower <- User.get_cached_by_ap_id(user.ap_id), + %User{} = followed <- User.get_or_fetch_by_nickname(nick), + {:ok, follower} <- User.follow(follower, followed) do + ActivityPub.follow(follower, followed) + else + _e -> Logger.debug "follow_import: following #{nick} failed" + end + end) + end) + + json conn, "job started" + end end diff --git a/lib/pleroma/web/twitter_api/representers/object_representer.ex b/lib/pleroma/web/twitter_api/representers/object_representer.ex index c39b60760..69eaeb36c 100644 --- a/lib/pleroma/web/twitter_api/representers/object_representer.ex +++ b/lib/pleroma/web/twitter_api/representers/object_representer.ex @@ -6,7 +6,7 @@ def to_map(%Object{} = object, _opts) do data = object.data url = List.first(data["url"]) %{ - url: url["href"], + url: url["href"] |> Pleroma.Web.MediaProxy.url(), mimetype: url["mediaType"], id: data["uuid"], oembed: false diff --git a/lib/pleroma/web/twitter_api/twitter_api.ex b/lib/pleroma/web/twitter_api/twitter_api.ex index d04a81cd4..faecebde0 100644 --- a/lib/pleroma/web/twitter_api/twitter_api.ex +++ b/lib/pleroma/web/twitter_api/twitter_api.ex @@ -316,10 +316,12 @@ def conversation_id_to_context(id) do def get_external_profile(for_user, uri) do with {:ok, %User{} = user} <- OStatus.find_or_make_user(uri) do - with url <- user.info["topic"], - {:ok, %{body: body}} <- @httpoison.get(url, [], follow_redirect: true, timeout: 10000, recv_timeout: 20000) do - OStatus.handle_incoming(body) - end + spawn(fn -> + with url <- user.info["topic"], + {:ok, %{body: body}} <- @httpoison.get(url, [], follow_redirect: true, timeout: 10000, recv_timeout: 20000) do + OStatus.handle_incoming(body) + end + end) {:ok, UserView.render("show.json", %{user: user, for: for_user})} else _e -> {:error, "Couldn't find user"} diff --git a/lib/pleroma/web/twitter_api/twitter_api_controller.ex b/lib/pleroma/web/twitter_api/twitter_api_controller.ex index 73d96c73d..5284a8847 100644 --- a/lib/pleroma/web/twitter_api/twitter_api_controller.ex +++ b/lib/pleroma/web/twitter_api/twitter_api_controller.ex @@ -263,16 +263,18 @@ def update_most_recent_notification(%{assigns: %{user: user}} = conn, %{"id" => end end - def followers(%{assigns: %{user: user}} = conn, _params) do - with {:ok, followers} <- User.get_followers(user) do + def followers(conn, params) do + with {:ok, user} <- TwitterAPI.get_user(conn.assigns.user, params), + {:ok, followers} <- User.get_followers(user) do render(conn, UserView, "index.json", %{users: followers, for: user}) else _e -> bad_request_reply(conn, "Can't get followers") end end - def friends(%{assigns: %{user: user}} = conn, _params) do - with {:ok, friends} <- User.get_friends(user) do + def friends(conn, params) do + with {:ok, user} <- TwitterAPI.get_user(conn.assigns.user, params), + {:ok, friends} <- User.get_friends(user) do render(conn, UserView, "index.json", %{users: friends, for: user}) else _e -> bad_request_reply(conn, "Can't get friends") diff --git a/lib/pleroma/web/twitter_api/views/user_view.ex b/lib/pleroma/web/twitter_api/views/user_view.ex index d1c7e6fbd..f49bcc0fb 100644 --- a/lib/pleroma/web/twitter_api/views/user_view.ex +++ b/lib/pleroma/web/twitter_api/views/user_view.ex @@ -2,6 +2,7 @@ defmodule Pleroma.Web.TwitterAPI.UserView do use Pleroma.Web, :view alias Pleroma.User alias Pleroma.Web.CommonAPI.Utils + alias Pleroma.Web.MediaProxy def render("show.json", %{user: user = %User{}} = assigns) do render_one(user, Pleroma.Web.TwitterAPI.UserView, "user.json", assigns) @@ -12,7 +13,7 @@ def render("index.json", %{users: users, for: user}) do end def render("user.json", %{user: user = %User{}} = assigns) do - image = User.avatar_url(user) + image = User.avatar_url(user) |> MediaProxy.url() {following, follows_you, statusnet_blocking} = if assigns[:for] do { User.following?(assigns[:for], user), @@ -44,8 +45,9 @@ def render("user.json", %{user: user = %User{}} = assigns) do "screen_name" => user.nickname, "statuses_count" => user_info[:note_count], "statusnet_profile_url" => user.ap_id, - "cover_photo" => image_url(user.info["banner"]), - "background_image" => image_url(user.info["background"]) + "cover_photo" => User.banner_url(user) |> MediaProxy.url(), + "background_image" => image_url(user.info["background"]) |> MediaProxy.url(), + "is_local" => user.local } if assigns[:token] do diff --git a/lib/pleroma/web/web_finger/web_finger.ex b/lib/pleroma/web/web_finger/web_finger.ex index 11b36d6ac..09957e133 100644 --- a/lib/pleroma/web/web_finger/web_finger.ex +++ b/lib/pleroma/web/web_finger/web_finger.ex @@ -45,7 +45,8 @@ def represent_user(user) do {:Link, %{rel: "http://webfinger.net/rel/profile-page", type: "text/html", href: user.ap_id}}, {:Link, %{rel: "salmon", href: OStatus.salmon_path(user)}}, {:Link, %{rel: "magic-public-key", href: "data:application/magic-public-key,#{magic_key}"}}, - {:Link, %{rel: "self", type: "application/activity+json", href: user.ap_id}} + {:Link, %{rel: "self", type: "application/activity+json", href: user.ap_id}}, + {:Link, %{rel: "http://ostatus.org/schema/1.0/subscribe", template: OStatus.remote_follow_path()}} ] } |> XmlBuilder.to_doc @@ -69,11 +70,13 @@ defp webfinger_from_xml(doc) do topic = XML.string_from_xpath(~s{//Link[@rel="http://schemas.google.com/g/2010#updates-from"]/@href}, doc) subject = XML.string_from_xpath("//Subject", doc) salmon = XML.string_from_xpath(~s{//Link[@rel="salmon"]/@href}, doc) + subscribe_address = XML.string_from_xpath(~s{//Link[@rel="http://ostatus.org/schema/1.0/subscribe"]/@template}, doc) data = %{ "magic_key" => magic_key, "topic" => topic, "subject" => subject, - "salmon" => salmon + "salmon" => salmon, + "subscribe_address" => subscribe_address } {:ok, data} end diff --git a/priv/static/emoji/blank.png b/priv/static/emoji/blank.png new file mode 100644 index 000000000..175a1d412 Binary files /dev/null and b/priv/static/emoji/blank.png differ diff --git a/priv/static/emoji/f_00b.png b/priv/static/emoji/f_00b.png new file mode 100644 index 000000000..8c0f8b7e8 Binary files /dev/null and b/priv/static/emoji/f_00b.png differ diff --git a/priv/static/emoji/f_00b11b.png b/priv/static/emoji/f_00b11b.png new file mode 100644 index 000000000..408b8fdd3 Binary files /dev/null and b/priv/static/emoji/f_00b11b.png differ diff --git a/priv/static/emoji/f_00b33b.png b/priv/static/emoji/f_00b33b.png new file mode 100644 index 000000000..7926f497c Binary files /dev/null and b/priv/static/emoji/f_00b33b.png differ diff --git a/priv/static/emoji/f_00h.png b/priv/static/emoji/f_00h.png new file mode 100644 index 000000000..a8e26b330 Binary files /dev/null and b/priv/static/emoji/f_00h.png differ diff --git a/priv/static/emoji/f_00t.png b/priv/static/emoji/f_00t.png new file mode 100644 index 000000000..5b78986f7 Binary files /dev/null and b/priv/static/emoji/f_00t.png differ diff --git a/priv/static/emoji/f_01b.png b/priv/static/emoji/f_01b.png new file mode 100644 index 000000000..13359359e Binary files /dev/null and b/priv/static/emoji/f_01b.png differ diff --git a/priv/static/emoji/f_03b.png b/priv/static/emoji/f_03b.png new file mode 100644 index 000000000..ab95f9b28 Binary files /dev/null and b/priv/static/emoji/f_03b.png differ diff --git a/priv/static/emoji/f_10b.png b/priv/static/emoji/f_10b.png new file mode 100644 index 000000000..b57b5b3b2 Binary files /dev/null and b/priv/static/emoji/f_10b.png differ diff --git a/priv/static/emoji/f_11b.png b/priv/static/emoji/f_11b.png new file mode 100644 index 000000000..dcdb61ea4 Binary files /dev/null and b/priv/static/emoji/f_11b.png differ diff --git a/priv/static/emoji/f_11b00b.png b/priv/static/emoji/f_11b00b.png new file mode 100644 index 000000000..48e487dff Binary files /dev/null and b/priv/static/emoji/f_11b00b.png differ diff --git a/priv/static/emoji/f_11b22b.png b/priv/static/emoji/f_11b22b.png new file mode 100644 index 000000000..a1f09b063 Binary files /dev/null and b/priv/static/emoji/f_11b22b.png differ diff --git a/priv/static/emoji/f_11h.png b/priv/static/emoji/f_11h.png new file mode 100644 index 000000000..59a86c98e Binary files /dev/null and b/priv/static/emoji/f_11h.png differ diff --git a/priv/static/emoji/f_11t.png b/priv/static/emoji/f_11t.png new file mode 100644 index 000000000..8a31379b1 Binary files /dev/null and b/priv/static/emoji/f_11t.png differ diff --git a/priv/static/emoji/f_12b.png b/priv/static/emoji/f_12b.png new file mode 100644 index 000000000..99481725e Binary files /dev/null and b/priv/static/emoji/f_12b.png differ diff --git a/priv/static/emoji/f_21b.png b/priv/static/emoji/f_21b.png new file mode 100644 index 000000000..d6f6e2131 Binary files /dev/null and b/priv/static/emoji/f_21b.png differ diff --git a/priv/static/emoji/f_22b.png b/priv/static/emoji/f_22b.png new file mode 100644 index 000000000..e90a407d9 Binary files /dev/null and b/priv/static/emoji/f_22b.png differ diff --git a/priv/static/emoji/f_22b11b.png b/priv/static/emoji/f_22b11b.png new file mode 100644 index 000000000..ca25cf1af Binary files /dev/null and b/priv/static/emoji/f_22b11b.png differ diff --git a/priv/static/emoji/f_22b33b.png b/priv/static/emoji/f_22b33b.png new file mode 100644 index 000000000..ec4760ca1 Binary files /dev/null and b/priv/static/emoji/f_22b33b.png differ diff --git a/priv/static/emoji/f_22h.png b/priv/static/emoji/f_22h.png new file mode 100644 index 000000000..c82c9179b Binary files /dev/null and b/priv/static/emoji/f_22h.png differ diff --git a/priv/static/emoji/f_22t.png b/priv/static/emoji/f_22t.png new file mode 100644 index 000000000..2a858a6f3 Binary files /dev/null and b/priv/static/emoji/f_22t.png differ diff --git a/priv/static/emoji/f_23b.png b/priv/static/emoji/f_23b.png new file mode 100644 index 000000000..551598a24 Binary files /dev/null and b/priv/static/emoji/f_23b.png differ diff --git a/priv/static/emoji/f_30b.png b/priv/static/emoji/f_30b.png new file mode 100644 index 000000000..f2cb32978 Binary files /dev/null and b/priv/static/emoji/f_30b.png differ diff --git a/priv/static/emoji/f_32b.png b/priv/static/emoji/f_32b.png new file mode 100644 index 000000000..5646a0fcd Binary files /dev/null and b/priv/static/emoji/f_32b.png differ diff --git a/priv/static/emoji/f_33b.png b/priv/static/emoji/f_33b.png new file mode 100644 index 000000000..86f2a0a0e Binary files /dev/null and b/priv/static/emoji/f_33b.png differ diff --git a/priv/static/emoji/f_33b00b.png b/priv/static/emoji/f_33b00b.png new file mode 100644 index 000000000..9f9a750b0 Binary files /dev/null and b/priv/static/emoji/f_33b00b.png differ diff --git a/priv/static/emoji/f_33b22b.png b/priv/static/emoji/f_33b22b.png new file mode 100644 index 000000000..48520a17e Binary files /dev/null and b/priv/static/emoji/f_33b22b.png differ diff --git a/priv/static/emoji/f_33h.png b/priv/static/emoji/f_33h.png new file mode 100644 index 000000000..0b8a333d2 Binary files /dev/null and b/priv/static/emoji/f_33h.png differ diff --git a/priv/static/emoji/f_33t.png b/priv/static/emoji/f_33t.png new file mode 100644 index 000000000..0f8812075 Binary files /dev/null and b/priv/static/emoji/f_33t.png differ diff --git a/priv/static/images/avi.png b/priv/static/images/avi.png new file mode 100644 index 000000000..336fd15ef Binary files /dev/null and b/priv/static/images/avi.png differ diff --git a/priv/static/images/banner.png b/priv/static/images/banner.png new file mode 100644 index 000000000..467c075d6 Binary files /dev/null and b/priv/static/images/banner.png differ diff --git a/priv/static/index.html b/priv/static/index.html index ba514c0f4..8571fa719 100644 --- a/priv/static/index.html +++ b/priv/static/index.html @@ -1 +1 @@ -Pleroma
\ No newline at end of file +Pleroma
\ No newline at end of file diff --git a/priv/static/instance/thumbnail.jpeg b/priv/static/instance/thumbnail.jpeg new file mode 100644 index 000000000..b7e012644 Binary files /dev/null and b/priv/static/instance/thumbnail.jpeg differ diff --git a/priv/static/static/config.json b/priv/static/static/config.json index 263107cea..8e4b21cad 100644 --- a/priv/static/static/config.json +++ b/priv/static/static/config.json @@ -1,7 +1,7 @@ { - "name": "Pleroma FE", "theme": "pleroma-dark", "background": "/static/bg.jpg", "logo": "/static/logo.png", - "registrationOpen": true + "defaultPath": "/main/all", + "chatDisabled": false } diff --git a/priv/static/static/css/app.67f64792f89a96e59442c437c7ded0b3.css b/priv/static/static/css/app.67f64792f89a96e59442c437c7ded0b3.css deleted file mode 100644 index b629d42b1..000000000 Binary files a/priv/static/static/css/app.67f64792f89a96e59442c437c7ded0b3.css and /dev/null differ diff --git a/priv/static/static/css/app.67f64792f89a96e59442c437c7ded0b3.css.map b/priv/static/static/css/app.67f64792f89a96e59442c437c7ded0b3.css.map deleted file mode 100644 index 6e32f2ca8..000000000 --- a/priv/static/static/css/app.67f64792f89a96e59442c437c7ded0b3.css.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"sources":["webpack:///webpack:///src/App.scss","webpack:///webpack:///src/components/login_form/login_form.vue","webpack:///webpack:///src/components/post_status_form/post_status_form.vue","webpack:///webpack:///src/components/media_upload/media_upload.vue","webpack:///webpack:///src/components/user_card_content/user_card_content.vue","webpack:///webpack:///src/components/nav_panel/nav_panel.vue","webpack:///webpack:///src/components/notifications/notifications.scss","webpack:///webpack:///src/components/status/status.vue","webpack:///webpack:///src/components/attachment/attachment.vue","webpack:///webpack:///src/components/favorite_button/favorite_button.vue","webpack:///webpack:///src/components/retweet_button/retweet_button.vue","webpack:///webpack:///src/components/delete_button/delete_button.vue","webpack:///webpack:///src/components/user_finder/user_finder.vue","webpack:///webpack:///src/components/timeline/timeline.vue","webpack:///webpack:///src/components/status_or_conversation/status_or_conversation.vue","webpack:///webpack:///src/components/user_card/user_card.vue","webpack:///webpack:///src/components/user_profile/user_profile.vue","webpack:///webpack:///src/components/settings/settings.vue","webpack:///webpack:///src/components/style_switcher/style_switcher.vue","webpack:///webpack:///src/components/registration/registration.vue","webpack:///webpack:///src/components/user_settings/user_settings.vue","webpack:///webpack:///src/components/chat/chat.vue"],"names":[],"mappings":"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","file":"static/css/app.67f64792f89a96e59442c437c7ded0b3.css","sourcesContent":["\n#app{background-size:cover;background-attachment:fixed;background-repeat:no-repeat;background-position:0 50px;min-height:100vh\n}\ni{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none\n}\nh4{margin:0\n}\n#content{box-sizing:border-box;padding-top:60px;margin:auto;min-height:100vh;max-width:980px;background-color:rgba(0,0,0,0.15);-ms-flex-line-pack:start;align-content:flex-start\n}\n.text-center{text-align:center\n}\nbody{font-family:sans-serif;font-size:14px;margin:0\n}\na{text-decoration:none\n}\nbutton{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:none;border-radius:5px;cursor:pointer;border-top:1px solid rgba(255,255,255,0.2);border-bottom:1px solid rgba(0,0,0,0.2);box-shadow:0px 0px 2px black;font-size:14px;font-family:sans-serif\n}\nbutton:hover{box-shadow:0px 0px 4px rgba(255,255,255,0.3)\n}\nbutton:disabled{cursor:not-allowed;opacity:0.5\n}\n.container{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin:0;padding:0 10px 0 10px\n}\n.gaps{margin:-1em 0 0 -1em\n}\n.item{-ms-flex:1;flex:1;line-height:21px;height:21px;overflow:hidden\n}\n.item .nav-icon{font-size:1.1em;margin-left:0.4em\n}\n.gaps>.item{padding:1em 0 0 1em\n}\n.auto-size{-ms-flex:1;flex:1\n}\nnav{width:100%;-ms-flex-align:center;align-items:center;position:fixed;height:50px\n}\nnav .inner-nav{padding-left:20px;padding-right:20px;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-preferred-size:970px;flex-basis:970px;margin:auto;height:50px;background-repeat:no-repeat;background-position:center;background-size:contain\n}\nmain-router{-ms-flex:1;flex:1\n}\n.status.compact{color:rgba(0,0,0,0.42);font-weight:300\n}\n.status.compact p{margin:0;font-size:0.8em\n}\n.panel{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;margin:0.5em;border-radius:10px;box-shadow:1px 1px 4px rgba(0,0,0,0.6);overflow:hidden\n}\n.panel-body:empty::before{content:\"¯\\\\_(ツ)_/¯\";display:block;margin:1em;text-align:center\n}\n.panel-heading{border-radius:10px 10px 0 0;background-size:cover;padding:0.6em 1.0em;text-align:left;font-size:1.3em;line-height:24px\n}\n.panel-footer{border-radius:0 0 10px 10px\n}\n.panel-body>p{line-height:18px;padding:1em;margin:0\n}\n.container>*{min-width:0px\n}\n.fa{color:grey\n}\nnav{z-index:1000;box-shadow:0px 0px 4px rgba(0,0,0,0.6)\n}\n.fade-enter-active,.fade-leave-active{transition:opacity .2s\n}\n.fade-enter,.fade-leave-active{opacity:0\n}\n.main{-ms-flex-preferred-size:60%;flex-basis:60%;-ms-flex-positive:1;flex-grow:1;-ms-flex-negative:1;flex-shrink:1\n}\n.sidebar-bounds{-ms-flex:0;flex:0;-ms-flex-preferred-size:35%;flex-basis:35%\n}\n.sidebar-flexer{-ms-flex:1;flex:1;-ms-flex-preferred-size:345px;flex-basis:345px;width:365px\n}\n.mobile-shown{display:none\n}\n.panel-switcher{display:none;width:100%;height:46px\n}\n.panel-switcher button{display:block;-ms-flex:1;flex:1;max-height:32px;margin:0.5em;padding:0.5em\n}\n@media all and (min-width: 960px){\nbody{overflow-y:scroll\n}\n.sidebar-bounds{overflow:hidden;max-height:100vh;width:345px;position:fixed;margin-top:-10px\n}\n.sidebar-bounds .sidebar-scroller{height:96vh;width:365px;padding-top:10px;padding-right:50px;overflow-x:hidden;overflow-y:scroll\n}\n.sidebar-bounds .sidebar{width:345px\n}\n.sidebar-flexer{max-height:96vh;-ms-flex-negative:0;flex-shrink:0;-ms-flex-positive:0;flex-grow:0\n}\n}\n@media all and (max-width: 959px){\n.mobile-hidden{display:none\n}\n.panel-switcher{display:-ms-flexbox;display:flex\n}\n.container{padding:0 0 0 0\n}\n.panel{margin:0.5em 0 0.5em 0\n}\n}\n.item.right{text-align:right;padding-right:20px\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/App.scss","\n.login-form input{border-width:1px;border-style:solid;border-color:silver;border-radius:5px;padding:0.1em 0.2em 0.2em 0.2em\n}\n.login-form .btn{min-height:28px;width:10em\n}\n.login-form .error{border-radius:5px;text-align:center;background-color:rgba(255,48,16,0.65);min-height:28px;line-height:28px\n}\n.login-form .register{-ms-flex:1 1;flex:1 1\n}\n.login-form .login-bottom{margin-top:1.0em;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/login_form/login_form.vue","\n.tribute-container ul{padding:0px\n}\n.tribute-container ul li{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center\n}\n.tribute-container img{padding:3px;width:16px;height:16px;border-radius:50%\n}\n.post-status-form .form-bottom,.login .form-bottom{display:-ms-flexbox;display:flex;padding:0.5em;height:32px\n}\n.post-status-form .form-bottom button,.login .form-bottom button{width:10em\n}\n.post-status-form .error,.login .error{border-radius:5px;text-align:center;background-color:rgba(255,48,16,0.65);padding:0.25em;margin:0.35em;display:-ms-flexbox;display:flex\n}\n.post-status-form .attachments,.login .attachments{padding:0 0.5em\n}\n.post-status-form .attachments .attachment,.login .attachments .attachment{position:relative;margin:0.5em 0.8em 0.2em 0\n}\n.post-status-form .attachments i,.login .attachments i{position:absolute;margin:10px;padding:5px;background:rgba(230,230,230,0.6);border-radius:5px;font-weight:bold\n}\n.post-status-form .btn,.login .btn{cursor:pointer\n}\n.post-status-form .btn[disabled],.login .btn[disabled]{cursor:not-allowed\n}\n.post-status-form .icon-cancel,.login .icon-cancel{cursor:pointer\n}\n.post-status-form form,.login form{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding:0.6em\n}\n.post-status-form .form-group,.login .form-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding:0.3em 0.5em 0.6em;line-height:24px\n}\n.post-status-form form textarea,.login form textarea{border:solid;border-width:1px;border-color:inherit;border-radius:5px;line-height:16px;padding:5px;resize:none;overflow:hidden\n}\n.post-status-form form textarea:focus,.login form textarea:focus{min-height:48px\n}\n.post-status-form .btn,.login .btn{cursor:pointer\n}\n.post-status-form .btn[disabled],.login .btn[disabled]{cursor:not-allowed\n}\n.post-status-form .icon-cancel,.login .icon-cancel{cursor:pointer;z-index:4\n}\n.post-status-form .autocomplete-panel,.login .autocomplete-panel{margin:0 0.5em 0 0.5em;border-radius:5px;position:absolute;z-index:1;box-shadow:1px 2px 4px rgba(0,0,0,0.5);min-width:75%\n}\n.post-status-form .autocomplete,.login .autocomplete{cursor:pointer;padding:0.2em 0.4em 0.2em 0.4em;border-bottom:1px solid rgba(0,0,0,0.4);display:-ms-flexbox;display:flex\n}\n.post-status-form .autocomplete img,.login .autocomplete img{width:24px;height:24px;border-radius:2px;object-fit:contain\n}\n.post-status-form .autocomplete span,.login .autocomplete span{line-height:24px;margin:0 0.1em 0 0.2em\n}\n.post-status-form .autocomplete small,.login .autocomplete small{font-style:italic\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/post_status_form/post_status_form.vue","\n.media-upload {\n font-size: 26px;\n -ms-flex: 1;\n flex: 1;\n}\n.icon-upload {\n cursor: pointer;\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/media_upload/media_upload.vue","\n.profile-panel-background{background-size:cover;border-radius:10px\n}\n.profile-panel-background .panel-heading{padding:0.6em 0em;text-align:center\n}\n.profile-panel-body{top:-0em;padding-top:4em;word-wrap:break-word\n}\n.user-info{color:white;padding:0 16px 16px 16px;margin-bottom:-4em;text-shadow:0px 1px 1.5px #000\n}\n.user-info .usersettings{color:white;opacity:0.8\n}\n.user-info .container{padding:16px 10px 4px 10px;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-direction:column;flex-direction:column;-ms-flex-line-pack:start;align-content:flex-start;-ms-flex-pack:center;justify-content:center;max-height:56px;overflow:hidden\n}\n.user-info img{border-radius:5px;-ms-flex:1 0 100%;flex:1 0 100%;width:56px;height:56px;box-shadow:0px 1px 8px rgba(0,0,0,0.75);object-fit:cover\n}\n.user-info .name-and-screen-name{display:block;margin-left:0.6em;text-align:left;text-overflow:ellipsis;white-space:nowrap\n}\n.user-info .user-name{color:white\n}\n.user-info .user-screen-name{color:white;font-weight:lighter;font-size:15px;padding-right:0.1em;-ms-flex:0 0 auto;flex:0 0 auto\n}\n.user-info .user-interactions{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-pack:justify;justify-content:space-between;margin-top:0.7em;margin-bottom:-1.0em\n}\n.user-info .user-interactions div{-ms-flex:1;flex:1\n}\n.user-info .user-interactions .following{color:white;font-size:14px;-ms-flex:0 0 100%;flex:0 0 100%;margin:-0.7em 0.0em 0.3em 0.0em;padding-left:16px;text-align:left\n}\n.user-info .user-interactions .mute{max-width:220px;min-height:28px\n}\n.user-info .user-interactions .follow{max-width:220px;min-height:28px\n}\n.user-info .user-interactions button{width:92%;height:100%\n}\n.user-info .user-interactions .pressed{border-bottom-color:rgba(255,255,255,0.2);border-top-color:rgba(0,0,0,0.2)\n}\n.user-counts{display:-ms-flexbox;display:flex;line-height:16px;padding:1em 1.5em 0em 1em;text-align:center\n}\n.user-count{-ms-flex:1;flex:1\n}\n.user-count h5{font-size:1em;font-weight:bolder;margin:0 0 0.25em\n}\n.user-count a{text-decoration:none\n}\n.dailyAvg{font-size:0.8em;opacity:0.5\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/user_card_content/user_card_content.vue","\n.nav-panel ul{list-style:none;margin:0;padding:0\n}\n.nav-panel li{border-bottom:1px solid;border-color:inherit;padding:0\n}\n.nav-panel li:first-child a{border-top-right-radius:10px;border-top-left-radius:10px\n}\n.nav-panel li:last-child a{border-bottom-right-radius:10px;border-bottom-left-radius:10px\n}\n.nav-panel li:last-child{border:none\n}\n.nav-panel a{display:block;padding:0.8em 0.85em\n}\n.nav-panel a:hover{background-color:transparent\n}\n.nav-panel a.router-link-active{font-weight:bolder;background-color:transparent\n}\n.nav-panel a.router-link-active:hover{text-decoration:underline\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/nav_panel/nav_panel.vue","\n.notifications{padding-bottom:15em\n}\n.notifications .panel-heading{position:relative\n}\n.notifications .panel-heading .read-button{position:absolute;right:0.7em;height:1.8em;line-height:100%\n}\n.notifications .unseen-count{display:inline-block;background-color:rgba(255,16,8,0.8);text-shadow:0px 0px 3px rgba(0,0,0,0.5);min-width:1.3em;border-radius:1.3em;margin:0 0.2em 0 -0.4em;color:white;font-size:0.9em;text-align:center;line-height:1.3em\n}\n.notifications .notification{padding:0.4em 0 0 10px;display:-ms-flexbox;display:flex;border-bottom:1px solid;border-bottom-color:inherit\n}\n.notifications .notification .text{min-width:0px;word-wrap:break-word;line-height:18px;position:relative;overflow:hidden;padding:0.3em 0.8em 0.5em\n}\n.notifications .notification .text .icon-retweet.lit{color:#0fa00f\n}\n.notifications .notification .text .icon-user-plus.lit{color:#0095ff\n}\n.notifications .notification .text .icon-reply.lit{color:#0095ff\n}\n.notifications .notification .text .icon-star.lit{color:orange\n}\n.notifications .notification .text .status-content{margin:0;max-height:300px\n}\n.notifications .notification .text h1{word-break:break-all;margin:0 0 0.3em;padding:0;font-size:1em;line-height:20px\n}\n.notifications .notification .text h1 small{font-weight:lighter\n}\n.notifications .notification .text p{margin:0;margin-top:0;margin-bottom:0.3em\n}\n.notifications .notification .avatar{padding-top:0.3em;width:32px;height:32px;border-radius:50%\n}\n.notifications .notification:last-child{border-bottom:none;border-radius:0 0 10px 10px\n}\n.notifications .notification-content{max-height:12em;overflow-y:hidden\n}\n.notifications .notification-gradient{position:absolute;width:100%;height:4em;margin-top:8em\n}\n.notifications .unseen{border-left:4px solid rgba(255,16,8,0.75);padding-left:6px\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/notifications/notifications.scss","\nstatus-text-container{display:block\n}\n.status-preview{position:absolute;max-width:34em;padding:0.5em;display:-ms-flexbox;display:flex;border-color:inherit;border-style:solid;border-width:1px;border-radius:4px;box-shadow:2px 2px 3px rgba(0,0,0,0.5);margin-top:0.5em;margin-left:1em\n}\n.status-preview .avatar{-ms-flex-negative:0;flex-shrink:0;width:32px;height:32px;border-radius:50%\n}\n.status-preview .text{padding:0 0.5em 0.5em 0.5em\n}\n.status-preview .text h4{margin-bottom:0.4em\n}\n.status-preview .text h4 small{font-weight:lighter\n}\n.status-preview-loading{display:block;font-size:2em;min-width:8em;text-align:center\n}\n.status-el{-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto;overflow-wrap:break-word;word-wrap:break-word;word-break:break-word;border-left-width:0px;line-height:18px\n}\n.timeline .status-el{border-bottom-width:1px;border-bottom-style:solid\n}\n.status-el .notify .avatar{border-width:3px;border-style:solid\n}\n.status-el .media-body{-ms-flex:1;flex:1;padding-left:0.5em\n}\n.status-el .user-content{min-height:52px;padding-top:1px\n}\n.status-el .media-heading{display:-ms-flexbox;display:flex;min-height:1.4em;margin-bottom:0.3em\n}\n.status-el .media-heading small{font-weight:lighter\n}\n.status-el .media-heading h4{margin-right:0.4em\n}\n.status-el .media-heading .name-and-links{-ms-flex:1 0;flex:1 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap\n}\n.status-el .media-heading .replies{-ms-flex-preferred-size:100%;flex-basis:100%\n}\n.status-el .expand{margin-right:-0.3em\n}\n.status-el a{display:inline-block;word-break:break-all\n}\n.status-el .status-content{margin:3px 15px 4px 0;max-height:400px;overflow-y:auto;overflow-x:hidden\n}\n.status-el .status-content img,.status-el .status-content video{max-width:100%;max-height:400px;object-fit:contain\n}\n.status-el .status-content blockquote{margin:0.2em 0 0.2em 2em;font-style:italic\n}\n.status-el p{margin:0;margin-top:0.2em;margin-bottom:0.5em\n}\n.status-el .media-left{margin:0.2em 0.3em 0 0\n}\n.status-el .media-left img{float:right;border-radius:5px\n}\n.status-el .retweet-info{padding:0.7em 0 0 0.6em\n}\n.status-el .retweet-info .media-left{display:-ms-flexbox;display:flex\n}\n.status-el .retweet-info .media-left i{-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;text-align:right;-ms-flex:1;flex:1;padding-right:0.3em\n}\n.status-fadein{animation-duration:0.5s;animation-name:fadein\n}\n@keyframes fadein{\nfrom{opacity:0\n}\nto{opacity:1\n}\n}\n.greentext{color:green\n}\n.status-conversation{border-left-style:solid\n}\n.status-actions{padding-top:0.15em;width:100%;display:-ms-flexbox;display:flex\n}\n.status-actions div,.status-actions favorite-button{max-width:6em;-ms-flex:1;flex:1\n}\n.icon-reply:hover{color:#0095ff\n}\n.icon-reply.icon-reply-active{color:#0095ff\n}\n.status .avatar{width:48px;height:48px\n}\n.status .avatar.retweeted{width:40px;height:40px;margin-right:8px;margin-bottom:8px\n}\n.status img.avatar-retweeter{width:24px;height:24px;position:absolute;margin-left:24px;margin-top:24px\n}\n.status.compact .avatar{width:32px\n}\n.status{padding:0.4em 0.7em 0.45em 0.7em;border-left:4px rgba(255,48,16,0.65);border-left-style:inherit\n}\n.status-conversation:last-child{border-bottom:none\n}\n.timeline .panel.timeline{border-radius:10px;overflow:hidden\n}\n.muted{padding:0.1em 0.4em 0.1em 0.8em\n}\n.muted button{margin-left:auto\n}\n.muted .muteWords{margin-left:10px\n}\na.unmute{display:block;margin-left:auto\n}\n.reply-left{-ms-flex:0;flex:0;min-width:48px\n}\n.reply-body{-ms-flex:1;flex:1\n}\n@media all and (max-width: 960px){\n.status-el .name-and-links{margin-left:-0.25em\n}\n.status{max-width:100%\n}\n.status .avatar{width:40px;height:40px\n}\n.status .avatar.retweeted{width:34px;height:34px;margin-right:8px;margin-bottom:8px\n}\n.status img.avatar-retweeter{width:22px;height:22px;position:absolute;margin-left:18px;margin-top:18px\n}\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/status/status.vue","\n.attachments{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-0.7em\n}\n.attachments .attachment.media-upload-container{-ms-flex:0 0 auto;flex:0 0 auto;max-height:300px;max-width:100%\n}\n.attachments .attachment{-ms-flex:1 0 30%;flex:1 0 30%;margin:0.5em 0.7em 0.6em 0.0em;-ms-flex-item-align:start;align-self:flex-start;border-style:solid;border-width:1px;border-radius:5px;overflow:hidden\n}\n.attachments .attachment.video{line-height:0\n}\n.attachments .attachment.html{-ms-flex-preferred-size:90%;flex-basis:90%;width:100%;display:-ms-flexbox;display:flex\n}\n.attachments .attachment.loading{cursor:progress\n}\n.attachments .attachment .hider{position:absolute;margin:10px;padding:5px;background:rgba(230,230,230,0.6);font-weight:bold;z-index:4\n}\n.attachments .attachment video{max-height:500px;height:100%;width:100%;z-index:0\n}\n.attachments .attachment audio{width:100%\n}\n.attachments .attachment img.media-upload{margin-bottom:-2px;max-height:300px;max-width:100%\n}\n.attachments .attachment .oembed{width:100%;margin-right:15px;display:-ms-flexbox;display:flex\n}\n.attachments .attachment .oembed img{width:100%\n}\n.attachments .attachment .oembed .image{-ms-flex:1;flex:1\n}\n.attachments .attachment .oembed .image img{border:0px;border-radius:5px;height:100%;object-fit:cover\n}\n.attachments .attachment .oembed .text{-ms-flex:2;flex:2;margin:8px;word-break:break-all\n}\n.attachments .attachment .oembed .text h1{font-size:14px;margin:0px\n}\n.attachments .attachment a.image-attachment{display:-ms-flexbox;display:flex;-ms-flex:1;flex:1\n}\n.attachments .attachment a.image-attachment img{object-fit:contain;width:100%;height:100%;max-height:500px\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/attachment/attachment.vue","\n.favorite-button{cursor:pointer;animation-duration:0.6s\n}\n.favorite-button:hover{color:orange\n}\n.favorite-button.icon-star{color:orange\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/favorite_button/favorite_button.vue","\n.icon-retweet{cursor:pointer;animation-duration:0.6s\n}\n.icon-retweet:hover{color:#0fa00f\n}\n.icon-retweet.retweeted{color:#0fa00f\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/retweet_button/retweet_button.vue","\n.icon-cancel,.delete-status{cursor:pointer\n}\n.icon-cancel:hover,.delete-status:hover{color:red\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/delete_button/delete_button.vue","\n.user-finder-container{height:21px;max-width:100%\n}\n.user-finder-input{border-width:1px;border-style:solid;border-color:inherit;border-radius:5px;max-width:80%;padding:0.1em 0.2em 0.2em 0.2em\n}\n.finder-error{background-color:rgba(255,48,16,0.65);margin:0.35em;border-radius:5px;padding:0.25em\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/user_finder/user_finder.vue","\n.timeline .timeline-heading{position:relative;display:-ms-flexbox;display:flex\n}\n.timeline .title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:70%\n}\n.timeline .loadmore-button{position:absolute;right:0.6em;font-size:14px;min-width:6em;height:1.8em;line-height:100%\n}\n.timeline .loadmore-text{position:absolute;right:0.6em;font-size:14px;min-width:6em;border-radius:5px;font-family:sans-serif;text-align:center;padding:0 0.5em 0 0.5em;opacity:0.8\n}\n.timeline .error{background-color:rgba(255,48,16,0.65)\n}\n.new-status-notification{position:relative;margin-top:-1px;font-size:1.1em;border-width:1px 0 0 0;border-style:solid;border-radius:0 0 10px 10px;padding:10px;z-index:1\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/timeline/timeline.vue","\n.spacer{height:1em\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/status_or_conversation/status_or_conversation.vue","\n.name-and-screen-name{margin-left:0.7em;margin-top:0.0em;margin-right:2em;text-align:left;width:100%\n}\n.follows-you{margin-left:2em;float:right\n}\n.card{display:-ms-flexbox;display:flex;-ms-flex:1 0;flex:1 0;padding-top:0.6em;padding-right:1em;padding-bottom:0.6em;padding-left:1em;border-bottom:1px solid;margin:0;border-bottom-color:inherit\n}\n.card .avatar{margin-top:0.2em;width:32px;height:32px;border-radius:50%\n}\n.usercard{width:-webkit-fill-available;width:-moz-webkit-fill-available;stretch:fill;margin:0.2em 0 0.7em 0;border-radius:10px;border-style:solid;border-color:inherit;border-width:1px;overflow:hidden\n}\n.usercard p{margin-bottom:0\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/user_card/user_card.vue","\n.user-profile{-ms-flex:2;flex:2;-ms-flex-preferred-size:500px;flex-basis:500px;padding-bottom:10px;border-radius:10px\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/user_profile/user_profile.vue","\n.setting-item{margin:1em 1em 1.4em\n}\n.setting-item textarea{width:100%;height:100px\n}\n.setting-item .old-avatar{width:128px;border-radius:5px\n}\n.setting-item .new-avatar{object-fit:cover;width:128px;height:128px;border-radius:5px\n}\n.setting-item .btn{margin-top:1em;min-height:28px;width:10em\n}\n.setting-list{list-style-type:none\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/settings/settings.vue","\n.style-switcher{margin-right:1em\n}\n.color-container{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap\n}\n.color-item{max-width:9em;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap\n}\n.theme-color-in{max-width:8em;border-radius:2px;border:0;padding:5px;margin:5px 0 5px 0\n}\n.theme-preview-content{padding:20px\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/style_switcher/style_switcher.vue","\n.registration-form{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;margin:0.6em\n}\n.registration-form .container{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row\n}\n.registration-form .terms-of-service{-ms-flex:0 1 50%;flex:0 1 50%;margin:0.8em\n}\n.registration-form .text-fields{margin-top:0.6em;-ms-flex:1 0;flex:1 0;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column\n}\n.registration-form .form-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding:0.3em 0.0em 0.3em;line-height:24px\n}\n.registration-form form textarea{border:solid;border-width:1px;border-color:silver;border-radius:5px;line-height:16px;padding:5px;resize:vertical\n}\n.registration-form input{border-width:1px;border-style:solid;border-color:silver;border-radius:5px;padding:0.1em 0.2em 0.2em 0.2em\n}\n.registration-form .captcha{max-width:350px;margin-bottom:0.4em\n}\n.registration-form .btn{margin-top:0.6em;height:28px\n}\n.registration-form .error{border-radius:5px;text-align:center;margin:0.5em 0.6em 0;background-color:rgba(255,48,16,0.65);min-height:28px;line-height:28px\n}\n@media all and (max-width: 959px){\n.registration-form .container{-ms-flex-direction:column-reverse;flex-direction:column-reverse\n}\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/registration/registration.vue","\n.profile-edit .name-changer{border-width:1px;border-style:solid;border-radius:5px;padding:0.2em 0.2em 0.2em 0.2em\n}\n.profile-edit .name-submit{padding:0.2em 0.5em 0.2em 0.5em\n}\n.profile-edit .bio{border-width:1px;border-style:solid;border-radius:5px;margin:0\n}\n.profile-edit .banner{max-width:400px;border-radius:5px\n}\n.profile-edit .uploading{font-size:1.5em;margin:0.25em\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/user_settings/user_settings.vue","\n.chat-message{padding:0.2em 0.5em\n}\n.chat-avatar img{height:32px;width:32px;border-radius:5px;margin-right:0.5em\n}\n.chat-input{display:-ms-flexbox;display:flex\n}\n.chat-input form{-ms-flex:auto;flex:auto\n}\n.chat-input form input{margin:0.5em;width:100%\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/chat/chat.vue"],"sourceRoot":""} \ No newline at end of file diff --git a/priv/static/static/css/app.b3deb1dd44970d86cc6b368f36fd09d9.css b/priv/static/static/css/app.b3deb1dd44970d86cc6b368f36fd09d9.css new file mode 100644 index 000000000..6aebbb3ba Binary files /dev/null and b/priv/static/static/css/app.b3deb1dd44970d86cc6b368f36fd09d9.css differ diff --git a/priv/static/static/css/app.b3deb1dd44970d86cc6b368f36fd09d9.css.map b/priv/static/static/css/app.b3deb1dd44970d86cc6b368f36fd09d9.css.map new file mode 100644 index 000000000..930c703e6 --- /dev/null +++ b/priv/static/static/css/app.b3deb1dd44970d86cc6b368f36fd09d9.css.map @@ -0,0 +1 @@ +{"version":3,"sources":["webpack:///webpack:///src/App.scss","webpack:///webpack:///src/components/login_form/login_form.vue","webpack:///webpack:///src/components/post_status_form/post_status_form.vue","webpack:///webpack:///src/components/media_upload/media_upload.vue","webpack:///webpack:///src/components/user_card_content/user_card_content.vue","webpack:///webpack:///src/components/nav_panel/nav_panel.vue","webpack:///webpack:///src/components/notifications/notifications.scss","webpack:///webpack:///src/components/status/status.vue","webpack:///webpack:///src/components/attachment/attachment.vue","webpack:///webpack:///src/components/favorite_button/favorite_button.vue","webpack:///webpack:///src/components/retweet_button/retweet_button.vue","webpack:///webpack:///src/components/delete_button/delete_button.vue","webpack:///webpack:///src/components/user_finder/user_finder.vue","webpack:///webpack:///src/components/chat_panel/chat_panel.vue","webpack:///webpack:///src/components/timeline/timeline.vue","webpack:///webpack:///src/components/status_or_conversation/status_or_conversation.vue","webpack:///webpack:///src/components/user_card/user_card.vue","webpack:///webpack:///src/components/user_profile/user_profile.vue","webpack:///webpack:///src/components/settings/settings.vue","webpack:///webpack:///src/components/style_switcher/style_switcher.vue","webpack:///webpack:///src/components/registration/registration.vue","webpack:///webpack:///src/components/user_settings/user_settings.vue"],"names":[],"mappings":"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","file":"static/css/app.b3deb1dd44970d86cc6b368f36fd09d9.css","sourcesContent":["\n#app{background-size:cover;background-attachment:fixed;background-repeat:no-repeat;background-position:0 50px;min-height:100vh\n}\ni{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none\n}\nh4{margin:0\n}\n#content{box-sizing:border-box;padding-top:60px;margin:auto;min-height:100vh;max-width:980px;background-color:rgba(0,0,0,0.15);-ms-flex-line-pack:start;align-content:flex-start\n}\n.text-center{text-align:center\n}\nbody{font-family:sans-serif;font-size:14px;margin:0\n}\na{text-decoration:none\n}\nbutton{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;border:none;border-radius:5px;cursor:pointer;border-top:1px solid rgba(255,255,255,0.2);border-bottom:1px solid rgba(0,0,0,0.2);box-shadow:0px 0px 2px black;font-size:14px;font-family:sans-serif\n}\nbutton:hover{box-shadow:0px 0px 4px rgba(255,255,255,0.3)\n}\nbutton:disabled{cursor:not-allowed;opacity:0.5\n}\n.container{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin:0;padding:0 10px 0 10px\n}\n.gaps{margin:-1em 0 0 -1em\n}\n.item{-ms-flex:1;flex:1;line-height:21px;height:21px;overflow:hidden\n}\n.item .nav-icon{font-size:1.1em;margin-left:0.4em\n}\n.gaps>.item{padding:1em 0 0 1em\n}\n.auto-size{-ms-flex:1;flex:1\n}\nnav{width:100%;-ms-flex-align:center;align-items:center;position:fixed;height:50px\n}\nnav .inner-nav{padding-left:20px;padding-right:20px;display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center;-ms-flex-preferred-size:970px;flex-basis:970px;margin:auto;height:50px;background-repeat:no-repeat;background-position:center;background-size:contain\n}\nmain-router{-ms-flex:1;flex:1\n}\n.status.compact{color:rgba(0,0,0,0.42);font-weight:300\n}\n.status.compact p{margin:0;font-size:0.8em\n}\n.panel{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;margin:0.5em;border-radius:10px;box-shadow:1px 1px 4px rgba(0,0,0,0.6);overflow:hidden\n}\n.panel-body:empty::before{content:\"¯\\\\_(ツ)_/¯\";display:block;margin:1em;text-align:center\n}\n.panel-heading{border-radius:10px 10px 0 0;background-size:cover;padding:0.6em 1.0em;text-align:left;font-size:1.3em;line-height:24px\n}\n.panel-footer{border-radius:0 0 10px 10px\n}\n.panel-body>p{line-height:18px;padding:1em;margin:0\n}\n.container>*{min-width:0px\n}\n.fa{color:grey\n}\nnav{z-index:1000;box-shadow:0px 0px 4px rgba(0,0,0,0.6)\n}\n.fade-enter-active,.fade-leave-active{transition:opacity .2s\n}\n.fade-enter,.fade-leave-active{opacity:0\n}\n.main{-ms-flex-preferred-size:60%;flex-basis:60%;-ms-flex-positive:1;flex-grow:1;-ms-flex-negative:1;flex-shrink:1\n}\n.sidebar-bounds{-ms-flex:0;flex:0;-ms-flex-preferred-size:35%;flex-basis:35%\n}\n.sidebar-flexer{-ms-flex:1;flex:1;-ms-flex-preferred-size:345px;flex-basis:345px;width:365px\n}\n.mobile-shown{display:none\n}\n.panel-switcher{display:none;width:100%;height:46px\n}\n.panel-switcher button{display:block;-ms-flex:1;flex:1;max-height:32px;margin:0.5em;padding:0.5em\n}\n@media all and (min-width: 960px){\nbody{overflow-y:scroll\n}\n.sidebar-bounds{overflow:hidden;max-height:100vh;width:345px;position:fixed;margin-top:-10px\n}\n.sidebar-bounds .sidebar-scroller{height:96vh;width:365px;padding-top:10px;padding-right:50px;overflow-x:hidden;overflow-y:scroll\n}\n.sidebar-bounds .sidebar{width:345px\n}\n.sidebar-flexer{max-height:96vh;-ms-flex-negative:0;flex-shrink:0;-ms-flex-positive:0;flex-grow:0\n}\n}\n@media all and (max-width: 959px){\n.mobile-hidden{display:none\n}\n.panel-switcher{display:-ms-flexbox;display:flex\n}\n.container{padding:0 0 0 0\n}\n.panel{margin:0.5em 0 0.5em 0\n}\n}\n.item.right{text-align:right;padding-right:20px\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/App.scss","\n.login-form input{border-width:1px;border-style:solid;border-color:silver;border-radius:5px;padding:0.1em 0.2em 0.2em 0.2em\n}\n.login-form .btn{min-height:28px;width:10em\n}\n.login-form .error{border-radius:5px;text-align:center;background-color:rgba(255,48,16,0.65);min-height:28px;line-height:28px\n}\n.login-form .register{-ms-flex:1 1;flex:1 1\n}\n.login-form .login-bottom{margin-top:1.0em;display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row;-ms-flex-align:center;align-items:center;-ms-flex-pack:justify;justify-content:space-between\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/login_form/login_form.vue","\n.tribute-container ul{padding:0px\n}\n.tribute-container ul li{display:-ms-flexbox;display:flex;-ms-flex-align:center;align-items:center\n}\n.tribute-container img{padding:3px;width:16px;height:16px;border-radius:50%\n}\n.post-status-form .form-bottom,.login .form-bottom{display:-ms-flexbox;display:flex;padding:0.5em;height:32px\n}\n.post-status-form .form-bottom button,.login .form-bottom button{width:10em\n}\n.post-status-form .form-bottom p,.login .form-bottom p{margin:0.35em;padding:0.35em;display:-ms-flexbox;display:flex\n}\n.post-status-form .error,.login .error{border-radius:5px;text-align:center;background-color:rgba(255,48,16,0.65);padding:0.25em;margin:0.35em;display:-ms-flexbox;display:flex\n}\n.post-status-form .attachments,.login .attachments{padding:0 0.5em\n}\n.post-status-form .attachments .attachment,.login .attachments .attachment{position:relative;margin:0.5em 0.8em 0.2em 0\n}\n.post-status-form .attachments i,.login .attachments i{position:absolute;margin:10px;padding:5px;background:rgba(230,230,230,0.6);border-radius:5px;font-weight:bold\n}\n.post-status-form .btn,.login .btn{cursor:pointer\n}\n.post-status-form .btn[disabled],.login .btn[disabled]{cursor:not-allowed\n}\n.post-status-form .icon-cancel,.login .icon-cancel{cursor:pointer\n}\n.post-status-form form,.login form{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding:0.6em\n}\n.post-status-form .form-group,.login .form-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding:0.3em 0.5em 0.6em;line-height:24px\n}\n.post-status-form form textarea,.login form textarea{border:solid;border-width:1px;border-color:inherit;border-radius:5px;line-height:16px;padding:5px;resize:none;overflow:hidden\n}\n.post-status-form form textarea:focus,.login form textarea:focus{min-height:48px\n}\n.post-status-form .btn,.login .btn{cursor:pointer\n}\n.post-status-form .btn[disabled],.login .btn[disabled]{cursor:not-allowed\n}\n.post-status-form .icon-cancel,.login .icon-cancel{cursor:pointer;z-index:4\n}\n.post-status-form .autocomplete-panel,.login .autocomplete-panel{margin:0 0.5em 0 0.5em;border-radius:5px;position:absolute;z-index:1;box-shadow:1px 2px 4px rgba(0,0,0,0.5);min-width:75%\n}\n.post-status-form .autocomplete,.login .autocomplete{cursor:pointer;padding:0.2em 0.4em 0.2em 0.4em;border-bottom:1px solid rgba(0,0,0,0.4);display:-ms-flexbox;display:flex\n}\n.post-status-form .autocomplete img,.login .autocomplete img{width:24px;height:24px;border-radius:2px;object-fit:contain\n}\n.post-status-form .autocomplete span,.login .autocomplete span{line-height:24px;margin:0 0.1em 0 0.2em\n}\n.post-status-form .autocomplete small,.login .autocomplete small{font-style:italic\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/post_status_form/post_status_form.vue","\n.media-upload {\n font-size: 26px;\n -ms-flex: 1;\n flex: 1;\n}\n.icon-upload {\n cursor: pointer;\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/media_upload/media_upload.vue","\n.profile-panel-background{background-size:cover;border-radius:10px\n}\n.profile-panel-background .panel-heading{padding:0.6em 0em;text-align:center\n}\n.profile-panel-body{top:-0em;padding-top:4em;word-wrap:break-word\n}\n.user-info{color:white;padding:0 16px 16px 16px;margin-bottom:-4em;text-shadow:0px 1px 1.5px #000\n}\n.user-info .usersettings{color:white;opacity:0.8\n}\n.user-info .container{padding:16px 10px 4px 10px;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-direction:column;flex-direction:column;-ms-flex-line-pack:start;align-content:flex-start;-ms-flex-pack:center;justify-content:center;max-height:56px;overflow:hidden\n}\n.user-info img{border-radius:5px;-ms-flex:1 0 100%;flex:1 0 100%;width:56px;height:56px;box-shadow:0px 1px 8px rgba(0,0,0,0.75);object-fit:cover\n}\n.user-info .name-and-screen-name{display:block;margin-left:0.6em;text-align:left;text-overflow:ellipsis;white-space:nowrap\n}\n.user-info .user-name{color:white\n}\n.user-info .user-screen-name{color:white;font-weight:lighter;font-size:15px;padding-right:0.1em;-ms-flex:0 0 auto;flex:0 0 auto\n}\n.user-info .user-interactions{display:-ms-flexbox;display:flex;-ms-flex-flow:row wrap;flex-flow:row wrap;-ms-flex-pack:justify;justify-content:space-between;margin-top:0.7em;margin-bottom:-1.0em\n}\n.user-info .user-interactions div{-ms-flex:1;flex:1\n}\n.user-info .user-interactions .following{color:white;font-size:14px;-ms-flex:0 0 100%;flex:0 0 100%;margin:-0.7em 0.0em 0.3em 0.0em;padding-left:16px;text-align:left\n}\n.user-info .user-interactions .mute{max-width:220px;min-height:28px\n}\n.user-info .user-interactions .remote-follow{max-width:220px;min-height:28px\n}\n.user-info .user-interactions .follow{max-width:220px;min-height:28px\n}\n.user-info .user-interactions button{width:92%;height:100%\n}\n.user-info .user-interactions .remote-button{height:28px !important;width:92%\n}\n.user-info .user-interactions .pressed{border-bottom-color:rgba(255,255,255,0.2);border-top-color:rgba(0,0,0,0.2)\n}\n.user-counts{display:-ms-flexbox;display:flex;line-height:16px;padding:1em 1.5em 0em 1em;text-align:center\n}\n.user-count{-ms-flex:1;flex:1\n}\n.user-count h5{font-size:1em;font-weight:bolder;margin:0 0 0.25em\n}\n.user-count a{text-decoration:none\n}\n.dailyAvg{font-size:0.8em;opacity:0.5\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/user_card_content/user_card_content.vue","\n.nav-panel ul{list-style:none;margin:0;padding:0\n}\n.nav-panel li{border-bottom:1px solid;border-color:inherit;padding:0\n}\n.nav-panel li:first-child a{border-top-right-radius:10px;border-top-left-radius:10px\n}\n.nav-panel li:last-child a{border-bottom-right-radius:10px;border-bottom-left-radius:10px\n}\n.nav-panel li:last-child{border:none\n}\n.nav-panel a{display:block;padding:0.8em 0.85em\n}\n.nav-panel a:hover{background-color:transparent\n}\n.nav-panel a.router-link-active{font-weight:bolder;background-color:transparent\n}\n.nav-panel a.router-link-active:hover{text-decoration:underline\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/nav_panel/nav_panel.vue","\n.notifications{padding-bottom:15em\n}\n.notifications .panel-heading{position:relative\n}\n.notifications .panel-heading .read-button{position:absolute;right:0.7em;height:1.8em;line-height:100%\n}\n.notifications .unseen-count{display:inline-block;background-color:rgba(255,16,8,0.8);text-shadow:0px 0px 3px rgba(0,0,0,0.5);min-width:1.3em;border-radius:1.3em;margin:0 0.2em 0 -0.4em;color:white;font-size:0.9em;text-align:center;line-height:1.3em\n}\n.notifications .notification{padding:0.4em 0 0 10px;display:-ms-flexbox;display:flex;border-bottom:1px solid;border-bottom-color:inherit\n}\n.notifications .notification .text{min-width:0px;word-wrap:break-word;line-height:18px;position:relative;overflow:hidden;padding:0.3em 0.8em 0.5em\n}\n.notifications .notification .text .icon-retweet.lit{color:#0fa00f\n}\n.notifications .notification .text .icon-user-plus.lit{color:#0095ff\n}\n.notifications .notification .text .icon-reply.lit{color:#0095ff\n}\n.notifications .notification .text .icon-star.lit{color:orange\n}\n.notifications .notification .text .status-content{margin:0;max-height:300px\n}\n.notifications .notification .text h1{word-break:break-all;margin:0 0 0.3em;padding:0;font-size:1em;line-height:20px\n}\n.notifications .notification .text h1 small{font-weight:lighter\n}\n.notifications .notification .text p{margin:0;margin-top:0;margin-bottom:0.3em\n}\n.notifications .notification .avatar{padding-top:0.3em;width:32px;height:32px;border-radius:50%\n}\n.notifications .notification:last-child{border-bottom:none;border-radius:0 0 10px 10px\n}\n.notifications .notification-content{max-height:12em;overflow-y:hidden\n}\n.notifications .notification-gradient{position:absolute;width:100%;height:4em;margin-top:8em\n}\n.notifications .unseen{border-left:4px solid rgba(255,16,8,0.75);padding-left:6px\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/notifications/notifications.scss","\nstatus-text-container{display:block\n}\n.status-preview{position:absolute;max-width:34em;padding:0.5em;display:-ms-flexbox;display:flex;border-color:inherit;border-style:solid;border-width:1px;border-radius:4px;box-shadow:2px 2px 3px rgba(0,0,0,0.5);margin-top:0.5em;margin-left:1em\n}\n.status-preview .avatar{-ms-flex-negative:0;flex-shrink:0;width:32px;height:32px;border-radius:50%\n}\n.status-preview .text{padding:0 0.5em 0.5em 0.5em\n}\n.status-preview .text h4{margin-bottom:0.4em\n}\n.status-preview .text h4 small{font-weight:lighter\n}\n.status-preview-loading{display:block;font-size:2em;min-width:8em;text-align:center\n}\n.status-el{-webkit-hyphens:auto;-ms-hyphens:auto;hyphens:auto;overflow-wrap:break-word;word-wrap:break-word;word-break:break-word;border-left-width:0px;line-height:18px\n}\n.timeline .status-el{border-bottom-width:1px;border-bottom-style:solid\n}\n.status-el .notify .avatar{border-width:3px;border-style:solid\n}\n.status-el .media-body{-ms-flex:1;flex:1;padding-left:0.5em\n}\n.status-el .user-content{min-height:52px;padding-top:1px\n}\n.status-el .media-heading{display:-ms-flexbox;display:flex;min-height:1.4em;margin-bottom:0.3em\n}\n.status-el .media-heading small{font-weight:lighter\n}\n.status-el .media-heading h4{margin-right:0.4em\n}\n.status-el .media-heading .name-and-links{-ms-flex:1 0;flex:1 0;display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap\n}\n.status-el .media-heading .replies{-ms-flex-preferred-size:100%;flex-basis:100%\n}\n.status-el .expand{margin-right:-0.3em\n}\n.status-el a{display:inline-block;word-break:break-all\n}\n.status-el .status-content{margin:3px 15px 4px 0;max-height:400px;overflow-y:auto;overflow-x:hidden\n}\n.status-el .status-content img,.status-el .status-content video{max-width:100%;max-height:400px;vertical-align:middle;object-fit:contain\n}\n.status-el .status-content blockquote{margin:0.2em 0 0.2em 2em;font-style:italic\n}\n.status-el p{margin:0;margin-top:0.2em;margin-bottom:0.5em\n}\n.status-el .media-left{margin:0.2em 0.3em 0 0\n}\n.status-el .media-left img{float:right;border-radius:5px\n}\n.status-el .retweet-info{padding:0.7em 0 0 0.6em\n}\n.status-el .retweet-info .media-left{display:-ms-flexbox;display:flex\n}\n.status-el .retweet-info .media-left i{-ms-flex-item-align:center;-ms-grid-row-align:center;align-self:center;text-align:right;-ms-flex:1;flex:1;padding-right:0.3em\n}\n.status-fadein{animation-duration:0.5s;animation-name:fadein\n}\n@keyframes fadein{\nfrom{opacity:0\n}\nto{opacity:1\n}\n}\n.greentext{color:green\n}\n.status-conversation{border-left-style:solid\n}\n.status-actions{padding-top:0.15em;width:100%;display:-ms-flexbox;display:flex\n}\n.status-actions div,.status-actions favorite-button{max-width:6em;-ms-flex:1;flex:1\n}\n.icon-reply:hover{color:#0095ff\n}\n.icon-reply.icon-reply-active{color:#0095ff\n}\n.status .avatar{width:48px;height:48px\n}\n.status .avatar.retweeted{width:40px;height:40px;margin-right:8px;margin-bottom:8px\n}\n.status img.avatar-retweeter{width:24px;height:24px;position:absolute;margin-left:24px;margin-top:24px\n}\n.status.compact .avatar{width:32px\n}\n.status{padding:0.4em 0.7em 0.45em 0.7em;border-left:4px rgba(255,48,16,0.65);border-left-style:inherit\n}\n.status-conversation:last-child{border-bottom:none\n}\n.timeline .panel.timeline{border-radius:10px;overflow:hidden\n}\n.muted{padding:0.1em 0.4em 0.1em 0.8em\n}\n.muted button{margin-left:auto\n}\n.muted .muteWords{margin-left:10px\n}\na.unmute{display:block;margin-left:auto\n}\n.reply-left{-ms-flex:0;flex:0;min-width:48px\n}\n.reply-body{-ms-flex:1;flex:1\n}\n@media all and (max-width: 960px){\n.status-el .name-and-links{margin-left:-0.25em\n}\n.status{max-width:100%\n}\n.status .avatar{width:40px;height:40px\n}\n.status .avatar.retweeted{width:34px;height:34px;margin-right:8px;margin-bottom:8px\n}\n.status img.avatar-retweeter{width:22px;height:22px;position:absolute;margin-left:18px;margin-top:18px\n}\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/status/status.vue","\n.attachments{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;margin-right:-0.7em\n}\n.attachments .attachment.media-upload-container{-ms-flex:0 0 auto;flex:0 0 auto;max-height:300px;max-width:100%\n}\n.attachments .attachment{-ms-flex:1 0 30%;flex:1 0 30%;margin:0.5em 0.7em 0.6em 0.0em;-ms-flex-item-align:start;align-self:flex-start;border-style:solid;border-width:1px;border-radius:5px;overflow:hidden\n}\n.attachments .attachment.video{line-height:0\n}\n.attachments .attachment.html{-ms-flex-preferred-size:90%;flex-basis:90%;width:100%;display:-ms-flexbox;display:flex\n}\n.attachments .attachment.loading{cursor:progress\n}\n.attachments .attachment .hider{position:absolute;margin:10px;padding:5px;background:rgba(230,230,230,0.6);font-weight:bold;z-index:4\n}\n.attachments .attachment video{max-height:500px;height:100%;width:100%;z-index:0\n}\n.attachments .attachment audio{width:100%\n}\n.attachments .attachment img.media-upload{margin-bottom:-2px;max-height:300px;max-width:100%\n}\n.attachments .attachment .oembed{width:100%;margin-right:15px;display:-ms-flexbox;display:flex\n}\n.attachments .attachment .oembed img{width:100%\n}\n.attachments .attachment .oembed .image{-ms-flex:1;flex:1\n}\n.attachments .attachment .oembed .image img{border:0px;border-radius:5px;height:100%;object-fit:cover\n}\n.attachments .attachment .oembed .text{-ms-flex:2;flex:2;margin:8px;word-break:break-all\n}\n.attachments .attachment .oembed .text h1{font-size:14px;margin:0px\n}\n.attachments .attachment a.image-attachment{display:-ms-flexbox;display:flex;-ms-flex:1;flex:1\n}\n.attachments .attachment a.image-attachment img{object-fit:contain;width:100%;height:100%;max-height:500px;image-orientation:from-image\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/attachment/attachment.vue","\n.fav-active{cursor:pointer;animation-duration:0.6s\n}\n.fav-active:hover{color:orange\n}\n.favorite-button.icon-star{color:orange\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/favorite_button/favorite_button.vue","\n.rt-active{cursor:pointer;animation-duration:0.6s\n}\n.rt-active:hover{color:#0fa00f\n}\n.icon-retweet.retweeted{color:#0fa00f\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/retweet_button/retweet_button.vue","\n.icon-cancel,.delete-status{cursor:pointer\n}\n.icon-cancel:hover,.delete-status:hover{color:red\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/delete_button/delete_button.vue","\n.user-finder-container{height:21px;max-width:100%\n}\n.user-finder-input{border-width:1px;border-style:solid;border-color:inherit;border-radius:5px;max-width:80%;padding:0.1em 0.2em 0.2em 0.2em\n}\n.finder-error{background-color:rgba(255,48,16,0.65);margin:0.35em;border-radius:5px;padding:0.25em\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/user_finder/user_finder.vue","\n.chat-window{max-height:200px;overflow-y:auto;overflow-x:hidden\n}\n.chat-message{padding:0.2em 0.5em\n}\n.chat-avatar img{height:32px;width:32px;border-radius:5px;margin-right:0.5em\n}\n.chat-input{display:-ms-flexbox;display:flex\n}\n.chat-input form{-ms-flex:auto;flex:auto\n}\n.chat-input form input{margin:0.5em;width:-webkit-fill-available;width:-moz-available;width:fill-available\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/chat_panel/chat_panel.vue","\n.timeline .timeline-heading{position:relative;display:-ms-flexbox;display:flex\n}\n.timeline .title{white-space:nowrap;overflow:hidden;text-overflow:ellipsis;max-width:70%\n}\n.timeline .loadmore-button{position:absolute;right:0.6em;font-size:14px;min-width:6em;height:1.8em;line-height:100%\n}\n.timeline .loadmore-text{position:absolute;right:0.6em;font-size:14px;min-width:6em;border-radius:5px;font-family:sans-serif;text-align:center;padding:0 0.5em 0 0.5em;opacity:0.8\n}\n.timeline .error{background-color:rgba(255,48,16,0.65)\n}\n.new-status-notification{position:relative;margin-top:-1px;font-size:1.1em;border-width:1px 0 0 0;border-style:solid;border-radius:0 0 10px 10px;padding:10px;z-index:1\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/timeline/timeline.vue","\n.spacer{height:1em\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/status_or_conversation/status_or_conversation.vue","\n.name-and-screen-name{margin-left:0.7em;margin-top:0.0em;margin-right:2em;text-align:left;width:100%\n}\n.follows-you{margin-left:2em;float:right\n}\n.card{display:-ms-flexbox;display:flex;-ms-flex:1 0;flex:1 0;padding-top:0.6em;padding-right:1em;padding-bottom:0.6em;padding-left:1em;border-bottom:1px solid;margin:0;border-bottom-color:inherit\n}\n.card .avatar{margin-top:0.2em;width:32px;height:32px;border-radius:50%\n}\n.usercard{width:-webkit-fill-available;width:-moz-available;width:fill-available;margin:0.2em 0 0.7em 0;border-radius:10px;border-style:solid;border-color:inherit;border-width:1px;overflow:hidden\n}\n.usercard p{margin-bottom:0\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/user_card/user_card.vue","\n.user-profile{-ms-flex:2;flex:2;-ms-flex-preferred-size:500px;flex-basis:500px;padding-bottom:10px;border-radius:10px\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/user_profile/user_profile.vue","\n.setting-item{margin:1em 1em 1.4em\n}\n.setting-item textarea{width:100%;height:100px\n}\n.setting-item .old-avatar{width:128px;border-radius:5px\n}\n.setting-item .new-avatar{object-fit:cover;width:128px;height:128px;border-radius:5px\n}\n.setting-item .btn{margin-top:1em;min-height:28px;width:10em\n}\n.setting-list{list-style-type:none\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/settings/settings.vue","\n.style-switcher{margin-right:1em\n}\n.color-container{display:-ms-flexbox;display:flex;-ms-flex-wrap:wrap;flex-wrap:wrap;-ms-flex-pack:justify;justify-content:space-between\n}\n.color-item{min-width:20em;display:-ms-flexbox;display:flex;-ms-flex:1 1 0px;flex:1 1 0;-ms-flex-align:baseline;align-items:baseline;margin:5px 6px 5px 0\n}\n.theme-color-cl,.theme-color-in{margin-left:4px;border-radius:2px;border:0\n}\n.theme-color-in{padding:5px;min-width:4em;max-width:7em;-ms-flex:1;flex:1\n}\n.theme-color-lb{-ms-flex:2;flex:2;min-width:7em;max-width:10em\n}\n.theme-color-cl{padding:1px;max-width:8em;-ms-flex-item-align:stretch;-ms-grid-row-align:stretch;align-self:stretch;height:100%;-ms-flex:0;flex:0;min-width:2em;cursor:pointer\n}\n.theme-preview-content{padding:20px\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/style_switcher/style_switcher.vue","\n.registration-form{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;margin:0.6em\n}\n.registration-form .container{display:-ms-flexbox;display:flex;-ms-flex-direction:row;flex-direction:row\n}\n.registration-form .terms-of-service{-ms-flex:0 1 50%;flex:0 1 50%;margin:0.8em\n}\n.registration-form .text-fields{margin-top:0.6em;-ms-flex:1 0;flex:1 0;display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column\n}\n.registration-form .form-group{display:-ms-flexbox;display:flex;-ms-flex-direction:column;flex-direction:column;padding:0.3em 0.0em 0.3em;line-height:24px\n}\n.registration-form form textarea{border:solid;border-width:1px;border-color:silver;border-radius:5px;line-height:16px;padding:5px;resize:vertical\n}\n.registration-form input{border-width:1px;border-style:solid;border-color:silver;border-radius:5px;padding:0.1em 0.2em 0.2em 0.2em\n}\n.registration-form .captcha{max-width:350px;margin-bottom:0.4em\n}\n.registration-form .btn{margin-top:0.6em;height:28px\n}\n.registration-form .error{border-radius:5px;text-align:center;margin:0.5em 0.6em 0;background-color:rgba(255,48,16,0.65);min-height:28px;line-height:28px\n}\n@media all and (max-width: 959px){\n.registration-form .container{-ms-flex-direction:column-reverse;flex-direction:column-reverse\n}\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/registration/registration.vue","\n.profile-edit .name-changer{border-width:1px;border-style:solid;border-radius:5px;padding:0.2em 0.2em 0.2em 0.2em\n}\n.profile-edit .name-submit{padding:0.2em 0.5em 0.2em 0.5em\n}\n.profile-edit .bio{border-width:1px;border-style:solid;border-radius:5px;margin:0\n}\n.profile-edit .banner{max-width:400px;border-radius:5px\n}\n.profile-edit .uploading{font-size:1.5em;margin:0.25em\n}\n\n\n\n// WEBPACK FOOTER //\n// webpack:///src/components/user_settings/user_settings.vue"],"sourceRoot":""} \ No newline at end of file diff --git a/priv/static/static/emoji.json b/priv/static/static/emoji.json new file mode 100644 index 000000000..0117bac1c --- /dev/null +++ b/priv/static/static/emoji.json @@ -0,0 +1 @@ +{"womans_clothes": "\ud83d\udc5a", "cookie": "\ud83c\udf6a", "woman_with_headscarf": "\ud83e\uddd5", "no_smoking": "\ud83d\udead", "e-mail": "\ud83d\udce7", "regional_indicator_d": "\ud83c\udde9", "oncoming_bus": "\ud83d\ude8d", "knife": "\ud83d\udd2a", "person_getting_haircut": "\ud83d\udc87", "grimacing": "\ud83d\ude2c", "ophiuchus": "\u26ce", "regional_indicator_q": "\ud83c\uddf6", "thinking": "\ud83e\udd14", "signal_strength": "\ud83d\udcf6", "cactus": "\ud83c\udf35", "bullettrain_front": "\ud83d\ude85", "floppy_disk": "\ud83d\udcbe", "doughnut": "\ud83c\udf69", "tv": "\ud83d\udcfa", "1234": "\ud83d\udd22", "anguished": "\ud83d\ude27", "clock1030": "\ud83d\udd65", "u7533": "\ud83c\ude38", "speak_no_evil": "\ud83d\ude4a", "chart_with_upwards_trend": "\ud83d\udcc8", "trophy": "\ud83c\udfc6", "musical_score": "\ud83c\udfbc", "chestnut": "\ud83c\udf30", "clock1130": "\ud83d\udd66", "abcd": "\ud83d\udd21", "syringe": "\ud83d\udc89", "shrimp": "\ud83e\udd90", "pisces": "\u2653", "left_facing_fist": "\ud83e\udd1b", "bar_chart": "\ud83d\udcca", "eagle": "\ud83e\udd85", "woman": "\ud83d\udc69", "keycap_ten": "\ud83d\udd1f", "yellow_heart": "\ud83d\udc9b", "croissant": "\ud83e\udd50", "mosque": "\ud83d\udd4c", "rice_ball": "\ud83c\udf59", "volcano": "\ud83c\udf0b", "baggage_claim": "\ud83d\udec4", "family": "\ud83d\udc6a", "beetle": "\ud83d\udc1e", "older_adult": "\ud83e\uddd3", "clock830": "\ud83d\udd63", "bacon": "\ud83e\udd53", "sound": "\ud83d\udd09", "no_bicycles": "\ud83d\udeb3", "rewind": "\u23ea", "adult": "\ud83e\uddd1", "scream_cat": "\ud83d\ude40", "person_playing_water_polo": "\ud83e\udd3d", "blue_car": "\ud83d\ude99", "smiley": "\ud83d\ude03", "kaaba": "\ud83d\udd4b", "twisted_rightwards_arrows": "\ud83d\udd00", "last_quarter_moon": "\ud83c\udf17", "first_place": "\ud83e\udd47", "joy_cat": "\ud83d\ude39", "sleeping": "\ud83d\ude34", "basketball": "\ud83c\udfc0", "pray": "\ud83d\ude4f", "trumpet": "\ud83c\udfba", "purple_heart": "\ud83d\udc9c", "broken_heart": "\ud83d\udc94", "astonished": "\ud83d\ude32", "soccer": "\u26bd", "princess": "\ud83d\udc78", "ant": "\ud83d\udc1c", "pig": "\ud83d\udc37", "vhs": "\ud83d\udcfc", "scream": "\ud83d\ude31", "mouse": "\ud83d\udc2d", "field_hockey": "\ud83c\udfd1", "ab": "\ud83c\udd8e", "tokyo_tower": "\ud83d\uddfc", "girl": "\ud83d\udc67", "u55b6": "\ud83c\ude3a", "guard": "\ud83d\udc82", "regional_indicator_s": "\ud83c\uddf8", "tulip": "\ud83c\udf37", "capital_abcd": "\ud83d\udd20", "beginner": "\ud83d\udd30", "couplekiss": "\ud83d\udc8f", "u5408": "\ud83c\ude34", "black_medium_small_square": "\u25fe", "paperclip": "\ud83d\udcce", "hedgehog": "\ud83e\udd94", "musical_note": "\ud83c\udfb5", "pill": "\ud83d\udc8a", "blue_heart": "\ud83d\udc99", "mens": "\ud83d\udeb9", "third_place": "\ud83e\udd49", "stew": "\ud83c\udf72", "prince": "\ud83e\udd34", "mortar_board": "\ud83c\udf93", "clock6": "\ud83d\udd55", "beer": "\ud83c\udf7a", "person_tipping_hand": "\ud83d\udc81", "triangular_ruler": "\ud83d\udcd0", "regional_indicator_y": "\ud83c\uddfe", "person_facepalming": "\ud83e\udd26", "steam_locomotive": "\ud83d\ude82", "fire_engine": "\ud83d\ude92", "horse": "\ud83d\udc34", "ribbon": "\ud83c\udf80", "white_large_square": "\u2b1c", "smirk": "\ud83d\ude0f", "genie": "\ud83e\uddde", "tangerine": "\ud83c\udf4a", "cl": "\ud83c\udd91", "japanese_goblin": "\ud83d\udc7a", "regional_indicator_u": "\ud83c\uddfa", "ring": "\ud83d\udc8d", "roller_coaster": "\ud83c\udfa2", "100": "\ud83d\udcaf", "clock12": "\ud83d\udd5b", "two_hearts": "\ud83d\udc95", "anger": "\ud83d\udca2", "black_circle": "\u26ab", "revolving_hearts": "\ud83d\udc9e", "space_invader": "\ud83d\udc7e", "bell": "\ud83d\udd14", "point_up_2": "\ud83d\udc46", "person_mountain_biking": "\ud83d\udeb5", "flags": "\ud83c\udf8f", "pushpin": "\ud83d\udccc", "large_blue_diamond": "\ud83d\udd37", "fairy": "\ud83e\uddda", "european_post_office": "\ud83c\udfe4", "statue_of_liberty": "\ud83d\uddfd", "man": "\ud83d\udc68", "microphone": "\ud83c\udfa4", "inbox_tray": "\ud83d\udce5", "bath": "\ud83d\udec0", "person_gesturing_ok": "\ud83d\ude46", "clap": "\ud83d\udc4f", "confused": "\ud83d\ude15", "fortune_cookie": "\ud83e\udd60", "kissing_closed_eyes": "\ud83d\ude1a", "kissing_heart": "\ud83d\ude18", "tropical_fish": "\ud83d\udc20", "taco": "\ud83c\udf2e", "kimono": "\ud83d\udc58", "u7a7a": "\ud83c\ude33", "rat": "\ud83d\udc00", "taurus": "\u2649", "shopping_cart": "\ud83d\uded2", "womans_hat": "\ud83d\udc52", "blossom": "\ud83c\udf3c", "moyai": "\ud83d\uddff", "clock130": "\ud83d\udd5c", "telescope": "\ud83d\udd2d", "running_shirt_with_sash": "\ud83c\udfbd", "person_running": "\ud83c\udfc3", "dizzy": "\ud83d\udcab", "crescent_moon": "\ud83c\udf19", "boom": "\ud83d\udca5", "restroom": "\ud83d\udebb", "fist": "\u270a", "white_flower": "\ud83d\udcae", "clown": "\ud83e\udd21", "neutral_face": "\ud83d\ude10", "id": "\ud83c\udd94", "carrot": "\ud83e\udd55", "rice_scene": "\ud83c\udf91", "foggy": "\ud83c\udf01", "turtle": "\ud83d\udc22", "mailbox_with_mail": "\ud83d\udcec", "baseball": "\u26be", "grin": "\ud83d\ude01", "bathtub": "\ud83d\udec1", "feet": "\ud83d\udc3e", "small_red_triangle": "\ud83d\udd3a", "camel": "\ud83d\udc2b", "aquarius": "\u2652", "face_with_symbols_over_mouth": "\ud83e\udd2c", "handbag": "\ud83d\udc5c", "date": "\ud83d\udcc5", "nail_care": "\ud83d\udc85", "satellite": "\ud83d\udce1", "candy": "\ud83c\udf6c", "white_medium_small_square": "\u25fd", "clock930": "\ud83d\udd64", "fearful": "\ud83d\ude28", "fork_and_knife": "\ud83c\udf74", "person_wearing_turban": "\ud83d\udc73", "confounded": "\ud83d\ude16", "helicopter": "\ud83d\ude81", "arrow_double_down": "\u23ec", "convenience_store": "\ud83c\udfea", "ghost": "\ud83d\udc7b", "bus": "\ud83d\ude8c", "waning_gibbous_moon": "\ud83c\udf16", "bank": "\ud83c\udfe6", "department_store": "\ud83c\udfec", "hockey": "\ud83c\udfd2", "fingers_crossed": "\ud83e\udd1e", "blond_haired_person": "\ud83d\udc71", "mag": "\ud83d\udd0d", "cut_of_meat": "\ud83e\udd69", "wink": "\ud83d\ude09", "railway_car": "\ud83d\ude83", "face_vomiting": "\ud83e\udd2e", "star_struck": "\ud83e\udd29", "first_quarter_moon_with_face": "\ud83c\udf1b", "octagonal_sign": "\ud83d\uded1", "hospital": "\ud83c\udfe5", "monkey": "\ud83d\udc12", "curly_loop": "\u27b0", "avocado": "\ud83e\udd51", "earth_americas": "\ud83c\udf0e", "flashlight": "\ud83d\udd26", "8ball": "\ud83c\udfb1", "clock630": "\ud83d\udd61", "boar": "\ud83d\udc17", "birthday": "\ud83c\udf82", "crocodile": "\ud83d\udc0a", "confetti_ball": "\ud83c\udf8a", "door": "\ud83d\udeaa", "school_satchel": "\ud83c\udf92", "peanuts": "\ud83e\udd5c", "regional_indicator_m": "\ud83c\uddf2", "bust_in_silhouette": "\ud83d\udc64", "sweat_drops": "\ud83d\udca6", "tongue": "\ud83d\udc45", "mag_right": "\ud83d\udd0e", "t_rex": "\ud83e\udd96", "post_office": "\ud83c\udfe3", "shell": "\ud83d\udc1a", "disappointed_relieved": "\ud83d\ude25", "card_index": "\ud83d\udcc7", "oncoming_automobile": "\ud83d\ude98", "passport_control": "\ud83d\udec2", "cherry_blossom": "\ud83c\udf38", "shallow_pan_of_food": "\ud83e\udd58", "heartbeat": "\ud83d\udc93", "crazy_face": "\ud83e\udd2a", "grapes": "\ud83c\udf47", "symbols": "\ud83d\udd23", "gift": "\ud83c\udf81", "scorpion": "\ud83e\udd82", "wedding": "\ud83d\udc92", "last_quarter_moon_with_face": "\ud83c\udf1c", "love_letter": "\ud83d\udc8c", "postal_horn": "\ud83d\udcef", "stuffed_flatbread": "\ud83e\udd59", "heavy_dollar_sign": "\ud83d\udcb2", "love_hotel": "\ud83c\udfe9", "yen": "\ud83d\udcb4", "person_in_steamy_room": "\ud83e\uddd6", "palm_tree": "\ud83c\udf34", "name_badge": "\ud83d\udcdb", "clock430": "\ud83d\udd5f", "bike": "\ud83d\udeb2", "snail": "\ud83d\udc0c", "bowling": "\ud83c\udfb3", "umbrella": "\u2614", "sleeping_accommodation": "\ud83d\udecc", "fireworks": "\ud83c\udf86", "closed_book": "\ud83d\udcd5", "city_sunset": "\ud83c\udf07", "persevere": "\ud83d\ude23", "bento": "\ud83c\udf71", "nut_and_bolt": "\ud83d\udd29", "page_facing_up": "\ud83d\udcc4", "snowman": "\u26c4", "two_women_holding_hands": "\ud83d\udc6d", "regional_indicator_o": "\ud83c\uddf4", "calling": "\ud83d\udcf2", "person_shrugging": "\ud83e\udd37", "sneezing_face": "\ud83e\udd27", "arrows_clockwise": "\ud83d\udd03", "no_pedestrians": "\ud83d\udeb7", "potato": "\ud83e\udd54", "cheese": "\ud83e\uddc0", "full_moon": "\ud83c\udf15", "mount_fuji": "\ud83d\uddfb", "sob": "\ud83d\ude2d", "construction": "\ud83d\udea7", "head_bandage": "\ud83e\udd15", "sailboat": "\u26f5", "slight_frown": "\ud83d\ude41", "ping_pong": "\ud83c\udfd3", "hatched_chick": "\ud83d\udc25", "sun_with_face": "\ud83c\udf1e", "seedling": "\ud83c\udf31", "repeat_one": "\ud83d\udd02", "muscle": "\ud83d\udcaa", "bridge_at_night": "\ud83c\udf09", "raised_hands": "\ud83d\ude4c", "house": "\ud83c\udfe0", "nerd": "\ud83e\udd13", "penguin": "\ud83d\udc27", "peach": "\ud83c\udf51", "dumpling": "\ud83e\udd5f", "watch": "\u231a", "womens": "\ud83d\udeba", "round_pushpin": "\ud83d\udccd", "alarm_clock": "\u23f0", "relieved": "\ud83d\ude0c", "sagittarius": "\u2650", "busstop": "\ud83d\ude8f", "regional_indicator_a": "\ud83c\udde6", "sandal": "\ud83d\udc61", "whale2": "\ud83d\udc0b", "book": "\ud83d\udcd6", "sweat": "\ud83d\ude13", "movie_camera": "\ud83c\udfa5", "clock230": "\ud83d\udd5d", "tiger": "\ud83d\udc2f", "tractor": "\ud83d\ude9c", "smile": "\ud83d\ude04", "vertical_traffic_light": "\ud83d\udea6", "exploding_head": "\ud83e\udd2f", "raised_hand": "\u270b", "smoking": "\ud83d\udeac", "page_with_curl": "\ud83d\udcc3", "exclamation": "\u2757", "fish": "\ud83d\udc1f", "mans_shoe": "\ud83d\udc5e", "sos": "\ud83c\udd98", "unlock": "\ud83d\udd13", "dolls": "\ud83c\udf8e", "ear_of_rice": "\ud83c\udf3e", "cat2": "\ud83d\udc08", "u7121": "\ud83c\ude1a", "repeat": "\ud83d\udd01", "cool": "\ud83c\udd92", "minibus": "\ud83d\ude90", "aerial_tramway": "\ud83d\udea1", "key": "\ud83d\udd11", "child": "\ud83e\uddd2", "camera": "\ud83d\udcf7", "sunflower": "\ud83c\udf3b", "white_check_mark": "\u2705", "white_square_button": "\ud83d\udd33", "banana": "\ud83c\udf4c", "milky_way": "\ud83c\udf0c", "person_gesturing_no": "\ud83d\ude45", "sushi": "\ud83c\udf63", "heart_eyes_cat": "\ud83d\ude3b", "guitar": "\ud83c\udfb8", "pie": "\ud83e\udd67", "calendar": "\ud83d\udcc6", "bear": "\ud83d\udc3b", "person_in_lotus_position": "\ud83e\uddd8", "clock10": "\ud83d\udd59", "top": "\ud83d\udd1d", "fuelpump": "\u26fd", "rainbow": "\ud83c\udf08", "snowboarder": "\ud83c\udfc2", "drum": "\ud83e\udd41", "leaves": "\ud83c\udf43", "first_quarter_moon": "\ud83c\udf13", "spoon": "\ud83e\udd44", "pouting_cat": "\ud83d\ude3e", "shaved_ice": "\ud83c\udf67", "unamused": "\ud83d\ude12", "train2": "\ud83d\ude86", "clock1230": "\ud83d\udd67", "regional_indicator_r": "\ud83c\uddf7", "fast_forward": "\u23e9", "accept": "\ud83c\ude51", "hammer": "\ud83d\udd28", "panda_face": "\ud83d\udc3c", "briefcase": "\ud83d\udcbc", "package": "\ud83d\udce6", "flag_black": "\ud83c\udff4", "smiling_imp": "\ud83d\ude08", "sunrise_over_mountains": "\ud83c\udf04", "airplane_departure": "\ud83d\udeeb", "tiger2": "\ud83d\udc05", "non-potable_water": "\ud83d\udeb1", "bird": "\ud83d\udc26", "barber": "\ud83d\udc88", "cry": "\ud83d\ude22", "billed_cap": "\ud83e\udde2", "pouch": "\ud83d\udc5d", "link": "\ud83d\udd17", "zebra": "\ud83e\udd93", "kiss": "\ud83d\udc8b", "scorpius": "\u264f", "prayer_beads": "\ud83d\udcff", "high_brightness": "\ud83d\udd06", "kissing_smiling_eyes": "\ud83d\ude19", "rhino": "\ud83e\udd8f", "left_luggage": "\ud83d\udec5", "o": "\u2b55", "crying_cat_face": "\ud83d\ude3f", "clock8": "\ud83d\udd57", "dress": "\ud83d\udc57", "clock7": "\ud83d\udd56", "bowl_with_spoon": "\ud83e\udd63", "rolling_eyes": "\ud83d\ude44", "fax": "\ud83d\udce0", "worried": "\ud83d\ude1f", "grey_question": "\u2754", "saxophone": "\ud83c\udfb7", "burrito": "\ud83c\udf2f", "salad": "\ud83e\udd57", "regional_indicator_z": "\ud83c\uddff", "bikini": "\ud83d\udc59", "milk": "\ud83e\udd5b", "stars": "\ud83c\udf20", "lips": "\ud83d\udc44", "cd": "\ud83d\udcbf", "weary": "\ud83d\ude29", "face_with_raised_eyebrow": "\ud83e\udd28", "lizard": "\ud83e\udd8e", "tone1": "\ud83c\udffb", "bullettrain_side": "\ud83d\ude84", "nose": "\ud83d\udc43", "innocent": "\ud83d\ude07", "wilted_rose": "\ud83e\udd40", "mahjong": "\ud83c\udc04", "factory": "\ud83c\udfed", "people_wrestling": "\ud83e\udd3c", "mailbox": "\ud83d\udceb", "rage": "\ud83d\ude21", "wheelchair": "\u267f", "x": "\u274c", "flower_playing_cards": "\ud83c\udfb4", "nauseated_face": "\ud83e\udd22", "underage": "\ud83d\udd1e", "ideograph_advantage": "\ud83c\ude50", "high_heel": "\ud83d\udc60", "dizzy_face": "\ud83d\ude35", "stuck_out_tongue": "\ud83d\ude1b", "mailbox_with_no_mail": "\ud83d\udced", "orange_heart": "\ud83e\udde1", "raised_back_of_hand": "\ud83e\udd1a", "footprints": "\ud83d\udc63", "notebook_with_decorative_cover": "\ud83d\udcd4", "mask": "\ud83d\ude37", "sunglasses": "\ud83d\ude0e", "pancakes": "\ud83e\udd5e", "regional_indicator_f": "\ud83c\uddeb", "dog": "\ud83d\udc36", "pig2": "\ud83d\udc16", "ng": "\ud83c\udd96", "unicorn": "\ud83e\udd84", "triumph": "\ud83d\ude24", "eggplant": "\ud83c\udf46", "egg": "\ud83e\udd5a", "office": "\ud83c\udfe2", "goat": "\ud83d\udc10", "handshake": "\ud83e\udd1d", "star": "\u2b50", "rugby_football": "\ud83c\udfc9", "call_me": "\ud83e\udd19", "rice_cracker": "\ud83c\udf58", "droplet": "\ud83d\udca7", "badminton": "\ud83c\udff8", "waxing_crescent_moon": "\ud83c\udf12", "ocean": "\ud83c\udf0a", "slot_machine": "\ud83c\udfb0", "wine_glass": "\ud83c\udf77", "elephant": "\ud83d\udc18", "blowfish": "\ud83d\udc21", "ledger": "\ud83d\udcd2", "money_mouth": "\ud83e\udd11", "heart_decoration": "\ud83d\udc9f", "arrow_down_small": "\ud83d\udd3d", "station": "\ud83d\ude89", "man_with_chinese_cap": "\ud83d\udc72", "vampire": "\ud83e\udddb", "pencil": "\ud83d\udcdd", "cyclone": "\ud83c\udf00", "mushroom": "\ud83c\udf44", "sandwich": "\ud83e\udd6a", "champagne": "\ud83c\udf7e", "expressionless": "\ud83d\ude11", "cold_sweat": "\ud83d\ude30", "maple_leaf": "\ud83c\udf41", "dromedary_camel": "\ud83d\udc2a", "vs": "\ud83c\udd9a", "person_fencing": "\ud83e\udd3a", "straight_ruler": "\ud83d\udccf", "baby_bottle": "\ud83c\udf7c", "currency_exchange": "\ud83d\udcb1", "regional_indicator_h": "\ud83c\udded", "stuck_out_tongue_closed_eyes": "\ud83d\ude1d", "closed_lock_with_key": "\ud83d\udd10", "eyes": "\ud83d\udc40", "water_buffalo": "\ud83d\udc03", "lock_with_ink_pen": "\ud83d\udd0f", "heavy_plus_sign": "\u2795", "bookmark": "\ud83d\udd16", "soon": "\ud83d\udd1c", "orange_book": "\ud83d\udcd9", "pineapple": "\ud83c\udf4d", "clock9": "\ud83d\udd58", "small_blue_diamond": "\ud83d\udd39", "black_large_square": "\u2b1b", "person_surfing": "\ud83c\udfc4", "leo": "\u264c", "merperson": "\ud83e\udddc", "canoe": "\ud83d\udef6", "rooster": "\ud83d\udc13", "hear_no_evil": "\ud83d\ude49", "corn": "\ud83c\udf3d", "takeout_box": "\ud83e\udd61", "oncoming_taxi": "\ud83d\ude96", "taxi": "\ud83d\ude95", "chart": "\ud83d\udcb9", "goal": "\ud83e\udd45", "melon": "\ud83c\udf48", "notes": "\ud83c\udfb6", "sparkler": "\ud83c\udf87", "dolphin": "\ud83d\udc2c", "speedboat": "\ud83d\udea4", "cancer": "\u264b", "sled": "\ud83d\udef7", "tanabata_tree": "\ud83c\udf8b", "train": "\ud83d\ude8b", "christmas_tree": "\ud83c\udf84", "two_men_holding_hands": "\ud83d\udc6c", "back": "\ud83d\udd19", "balloon": "\ud83c\udf88", "checkered_flag": "\ud83c\udfc1", "loop": "\u27bf", "wc": "\ud83d\udebe", "jeans": "\ud83d\udc56", "green_apple": "\ud83c\udf4f", "crown": "\ud83d\udc51", "cowboy": "\ud83e\udd20", "postbox": "\ud83d\udcee", "volleyball": "\ud83c\udfd0", "upside_down": "\ud83d\ude43", "cricket": "\ud83e\udd97", "custard": "\ud83c\udf6e", "rose": "\ud83c\udf39", "eyeglasses": "\ud83d\udc53", "oncoming_police_car": "\ud83d\ude94", "atm": "\ud83c\udfe7", "flying_saucer": "\ud83d\udef8", "alien": "\ud83d\udc7d", "hamster": "\ud83d\udc39", "trident": "\ud83d\udd31", "disappointed": "\ud83d\ude1e", "cow": "\ud83d\udc2e", "police_officer": "\ud83d\udc6e", "popcorn": "\ud83c\udf7f", "baby_chick": "\ud83d\udc24", "video_camera": "\ud83d\udcf9", "zzz": "\ud83d\udca4", "person_climbing": "\ud83e\uddd7", "star2": "\ud83c\udf1f", "ok": "\ud83c\udd97", "capricorn": "\u2651", "chicken": "\ud83d\udc14", "arrow_double_up": "\u23eb", "zombie": "\ud83e\udddf", "closed_umbrella": "\ud83c\udf02", "person_walking": "\ud83d\udeb6", "lemon": "\ud83c\udf4b", "heartpulse": "\ud83d\udc97", "regional_indicator_i": "\ud83c\uddee", "sauropod": "\ud83e\udd95", "u7981": "\ud83c\ude32", "regional_indicator_w": "\ud83c\uddfc", "evergreen_tree": "\ud83c\udf32", "mobile_phone_off": "\ud83d\udcf4", "koko": "\ud83c\ude01", "poop": "\ud83d\udca9", "cup_with_straw": "\ud83e\udd64", "leopard": "\ud83d\udc06", "radio_button": "\ud83d\udd18", "mega": "\ud83d\udce3", "metal": "\ud83e\udd18", "shushing_face": "\ud83e\udd2b", "stuck_out_tongue_winking_eye": "\ud83d\ude1c", "octopus": "\ud83d\udc19", "boxing_glove": "\ud83e\udd4a", "person_juggling": "\ud83e\udd39", "money_with_wings": "\ud83d\udcb8", "dollar": "\ud83d\udcb5", "bride_with_veil": "\ud83d\udc70", "second_place": "\ud83e\udd48", "spaghetti": "\ud83c\udf5d", "waning_crescent_moon": "\ud83c\udf18", "football": "\ud83c\udfc8", "white_circle": "\u26aa", "full_moon_with_face": "\ud83c\udf1d", "selfie": "\ud83e\udd33", "tone3": "\ud83c\udffd", "rabbit": "\ud83d\udc30", "computer": "\ud83d\udcbb", "clock11": "\ud83d\udd5a", "heavy_minus_sign": "\u2796", "synagogue": "\ud83d\udd4d", "hourglass": "\u231b", "gem": "\ud83d\udc8e", "person_doing_cartwheel": "\ud83e\udd38", "new_moon_with_face": "\ud83c\udf1a", "sunrise": "\ud83c\udf05", "regional_indicator_x": "\ud83c\uddfd", "open_file_folder": "\ud83d\udcc2", "gift_heart": "\ud83d\udc9d", "tada": "\ud83c\udf89", "green_heart": "\ud83d\udc9a", "battery": "\ud83d\udd0b", "regional_indicator_t": "\ud83c\uddf9", "wrench": "\ud83d\udd27", "aries": "\u2648", "man_in_tuxedo": "\ud83e\udd35", "regional_indicator_e": "\ud83c\uddea", "regional_indicator_l": "\ud83c\uddf1", "cake": "\ud83c\udf70", "clapper": "\ud83c\udfac", "japanese_castle": "\ud83c\udfef", "crystal_ball": "\ud83d\udd2e", "golf": "\u26f3", "no_mobile_phones": "\ud83d\udcf5", "person_biking": "\ud83d\udeb4", "icecream": "\ud83c\udf66", "mage": "\ud83e\uddd9", "bookmark_tabs": "\ud83d\udcd1", "tone4": "\ud83c\udffe", "mountain_cableway": "\ud83d\udea0", "person_playing_handball": "\ud83e\udd3e", "bulb": "\ud83d\udca1", "clock330": "\ud83d\udd5e", "metro": "\ud83d\ude87", "wave": "\ud83d\udc4b", "whale": "\ud83d\udc33", "strawberry": "\ud83c\udf53", "hatching_chick": "\ud83d\udc23", "trolleybus": "\ud83d\ude8e", "lollipop": "\ud83c\udf6d", "clipboard": "\ud83d\udccb", "point_right": "\ud83d\udc49", "u6307": "\ud83c\ude2f", "santa": "\ud83c\udf85", "hibiscus": "\ud83c\udf3a", "green_book": "\ud83d\udcd7", "skull": "\ud83d\udc80", "tumbler_glass": "\ud83e\udd43", "clock2": "\ud83d\udd51", "open_mouth": "\ud83d\ude2e", "bouquet": "\ud83d\udc90", "champagne_glass": "\ud83e\udd42", "poodle": "\ud83d\udc29", "hushed": "\ud83d\ude2f", "earth_asia": "\ud83c\udf0f", "face_with_monocle": "\ud83e\uddd0", "libra": "\u264e", "clock5": "\ud83d\udd54", "ambulance": "\ud83d\ude91", "u5272": "\ud83c\ude39", "lipstick": "\ud83d\udc84", "apple": "\ud83c\udf4e", "headphones": "\ud83c\udfa7", "turkey": "\ud83e\udd83", "pretzel": "\ud83e\udd68", "bug": "\ud83d\udc1b", "school": "\ud83c\udfeb", "speaker": "\ud83d\udd08", "boot": "\ud83d\udc62", "cat": "\ud83d\udc31", "dancer": "\ud83d\udc83", "no_entry": "\u26d4", "kissing_cat": "\ud83d\ude3d", "art": "\ud83c\udfa8", "coat": "\ud83e\udde5", "credit_card": "\ud83d\udcb3", "customs": "\ud83d\udec3", "broccoli": "\ud83e\udd66", "point_left": "\ud83d\udc48", "canned_food": "\ud83e\udd6b", "sheep": "\ud83d\udc11", "person_bowing": "\ud83d\ude47", "scroll": "\ud83d\udcdc", "martial_arts_uniform": "\ud83e\udd4b", "amphora": "\ud83c\udffa", "thought_balloon": "\ud83d\udcad", "no_bell": "\ud83d\udd15", "musical_keyboard": "\ud83c\udfb9", "people_with_bunny_ears_partying": "\ud83d\udc6f", "european_castle": "\ud83c\udff0", "punch": "\ud83d\udc4a", "camera_with_flash": "\ud83d\udcf8", "regional_indicator_p": "\ud83c\uddf5", "red_car": "\ud83d\ude97", "regional_indicator_j": "\ud83c\uddef", "owl": "\ud83e\udd89", "chart_with_downwards_trend": "\ud83d\udcc9", "older_woman": "\ud83d\udc75", "gemini": "\u264a", "incoming_envelope": "\ud83d\udce8", "waxing_gibbous_moon": "\ud83c\udf14", "toilet": "\ud83d\udebd", "dragon_face": "\ud83d\udc32", "koala": "\ud83d\udc28", "tone5": "\ud83c\udfff", "kiwi": "\ud83e\udd5d", "dash": "\ud83d\udca8", "imp": "\ud83d\udc7f", "tent": "\u26fa", "regional_indicator_b": "\ud83c\udde7", "monorail": "\ud83d\ude9d", "ox": "\ud83d\udc02", "giraffe": "\ud83e\udd92", "new": "\ud83c\udd95", "person_raising_hand": "\ud83d\ude4b", "japan": "\ud83d\uddfe", "rice": "\ud83c\udf5a", "ticket": "\ud83c\udfab", "rotating_light": "\ud83d\udea8", "loudspeaker": "\ud83d\udce2", "person_getting_massage": "\ud83d\udc86", "loud_sound": "\ud83d\udd0a", "hugging": "\ud83e\udd17", "herb": "\ud83c\udf3f", "baby": "\ud83d\udc76", "angel": "\ud83d\udc7c", "athletic_shoe": "\ud83d\udc5f", "euro": "\ud83d\udcb6", "ram": "\ud83d\udc0f", "large_orange_diamond": "\ud83d\udd36", "red_circle": "\ud83d\udd34", "ferris_wheel": "\ud83c\udfa1", "drooling_face": "\ud83e\udd24", "microscope": "\ud83d\udd2c", "middle_finger": "\ud83d\udd95", "pager": "\ud83d\udcdf", "pensive": "\ud83d\ude14", "potable_water": "\ud83d\udeb0", "abc": "\ud83d\udd24", "four_leaf_clover": "\ud83c\udf40", "vulcan": "\ud83d\udd96", "french_bread": "\ud83e\udd56", "motor_scooter": "\ud83d\udef5", "moneybag": "\ud83d\udcb0", "sparkles": "\u2728", "gloves": "\ud83e\udde4", "envelope_with_arrow": "\ud83d\udce9", "thumbsdown": "\ud83d\udc4e", "regional_indicator_g": "\ud83c\uddec", "video_game": "\ud83c\udfae", "on": "\ud83d\udd1b", "open_hands": "\ud83d\udc50", "monkey_face": "\ud83d\udc35", "mountain_railway": "\ud83d\ude9e", "bee": "\ud83d\udc1d", "scooter": "\ud83d\udef4", "fishing_pole_and_fish": "\ud83c\udfa3", "smiley_cat": "\ud83d\ude3a", "heart_eyes": "\ud83d\ude0d", "horse_racing": "\ud83c\udfc7", "ear": "\ud83d\udc42", "blue_circle": "\ud83d\udd35", "crossed_flags": "\ud83c\udf8c", "black_joker": "\ud83c\udccf", "six_pointed_star": "\ud83d\udd2f", "fountain": "\u26f2", "free": "\ud83c\udd93", "tennis": "\ud83c\udfbe", "yum": "\ud83d\ude0b", "fried_shrimp": "\ud83c\udf64", "dragon": "\ud83d\udc09", "purse": "\ud83d\udc5b", "clock1": "\ud83d\udd50", "airplane_arriving": "\ud83d\udeec", "cucumber": "\ud83e\udd52", "man_dancing": "\ud83d\udd7a", "clock730": "\ud83d\udd62", "deer": "\ud83e\udd8c", "meat_on_bone": "\ud83c\udf56", "bomb": "\ud83d\udca3", "night_with_stars": "\ud83c\udf03", "snake": "\ud83d\udc0d", "ramen": "\ud83c\udf5c", "end": "\ud83d\udd1a", "do_not_litter": "\ud83d\udeaf", "joy": "\ud83d\ude02", "light_rail": "\ud83d\ude88", "game_die": "\ud83c\udfb2", "violin": "\ud83c\udfbb", "tone2": "\ud83c\udffc", "tropical_drink": "\ud83c\udf79", "love_you_gesture": "\ud83e\udd1f", "cherries": "\ud83c\udf52", "traffic_light": "\ud83d\udea5", "iphone": "\ud83d\udcf1", "socks": "\ud83e\udde6", "wind_chime": "\ud83c\udf90", "no_entry_sign": "\ud83d\udeab", "elf": "\ud83e\udddd", "squid": "\ud83e\udd91", "person_pouting": "\ud83d\ude4e", "smile_cat": "\ud83d\ude38", "beers": "\ud83c\udf7b", "minidisc": "\ud83d\udcbd", "clock4": "\ud83d\udd53", "ice_cream": "\ud83c\udf68", "cocktail": "\ud83c\udf78", "clock3": "\ud83d\udd52", "frowning": "\ud83d\ude26", "hamburger": "\ud83c\udf54", "brain": "\ud83e\udde0", "heavy_division_sign": "\u2797", "tophat": "\ud83c\udfa9", "no_mouth": "\ud83d\ude36", "ski": "\ud83c\udfbf", "right_facing_fist": "\ud83e\udd1c", "mailbox_closed": "\ud83d\udcea", "chocolate_bar": "\ud83c\udf6b", "rabbit2": "\ud83d\udc07", "honey_pot": "\ud83c\udf6f", "izakaya_lantern": "\ud83c\udfee", "articulated_lorry": "\ud83d\ude9b", "face_with_hand_over_mouth": "\ud83e\udd2d", "japanese_ogre": "\ud83d\udc79", "zap": "\u26a1", "rocket": "\ud83d\ude80", "pizza": "\ud83c\udf55", "pound": "\ud83d\udcb7", "person_swimming": "\ud83c\udfca", "anchor": "\u2693", "coconut": "\ud83e\udd65", "sparkling_heart": "\ud83d\udc96", "older_man": "\ud83d\udc74", "mouse2": "\ud83d\udc01", "angry": "\ud83d\ude20", "up": "\ud83c\udd99", "gorilla": "\ud83e\udd8d", "children_crossing": "\ud83d\udeb8", "smirk_cat": "\ud83d\ude3c", "pregnant_woman": "\ud83e\udd30", "electric_plug": "\ud83d\udd0c", "dog2": "\ud83d\udc15", "question": "\u2753", "carousel_horse": "\ud83c\udfa0", "church": "\u26ea", "outbox_tray": "\ud83d\udce4", "cinema": "\ud83c\udfa6", "flushed": "\ud83d\ude33", "blush": "\ud83d\ude0a", "medal": "\ud83c\udfc5", "coffee": "\u2615", "gun": "\ud83d\udd2b", "city_dusk": "\ud83c\udf06", "watermelon": "\ud83c\udf49", "cricket_game": "\ud83c\udfcf", "shower": "\ud83d\udebf", "mute": "\ud83d\udd07", "breast_feeding": "\ud83e\udd31", "sweat_smile": "\ud83d\ude05", "construction_worker": "\ud83d\udc77", "cow2": "\ud83d\udc04", "arrows_counterclockwise": "\ud83d\udd04", "u6e80": "\ud83c\ude35", "grinning": "\ud83d\ude00", "globe_with_meridians": "\ud83c\udf10", "diamond_shape_with_a_dot_inside": "\ud83d\udca0", "deciduous_tree": "\ud83c\udf33", "shark": "\ud83e\udd88", "tram": "\ud83d\ude8a", "person_rowing_boat": "\ud83d\udea3", "chopsticks": "\ud83e\udd62", "black_heart": "\ud83d\udda4", "seat": "\ud83d\udcba", "kissing": "\ud83d\ude17", "laughing": "\ud83d\ude06", "slight_smile": "\ud83d\ude42", "radio": "\ud83d\udcfb", "arrow_up_small": "\ud83d\udd3c", "dango": "\ud83c\udf61", "rofl": "\ud83e\udd23", "see_no_evil": "\ud83d\ude48", "thermometer_face": "\ud83e\udd12", "hotdog": "\ud83c\udf2d", "virgo": "\u264d", "poultry_leg": "\ud83c\udf57", "hotel": "\ud83c\udfe8", "wolf": "\ud83d\udc3a", "curry": "\ud83c\udf5b", "regional_indicator_v": "\ud83c\uddfb", "crab": "\ud83e\udd80", "tired_face": "\ud83d\ude2b", "place_of_worship": "\ud83d\uded0", "ok_hand": "\ud83d\udc4c", "speech_balloon": "\ud83d\udcac", "sleepy": "\ud83d\ude2a", "earth_africa": "\ud83c\udf0d", "police_car": "\ud83d\ude93", "small_red_triangle_down": "\ud83d\udd3b", "bearded_person": "\ud83e\uddd4", "curling_stone": "\ud83e\udd4c", "scarf": "\ud83e\udde3", "fire": "\ud83d\udd25", "file_folder": "\ud83d\udcc1", "zipper_mouth": "\ud83e\udd10", "new_moon": "\ud83c\udf11", "regional_indicator_n": "\ud83c\uddf3", "negative_squared_cross_mark": "\u274e", "newspaper": "\ud83d\udcf0", "dvd": "\ud83d\udcc0", "pear": "\ud83c\udf50", "partly_sunny": "\u26c5", "black_square_button": "\ud83d\udd32", "low_brightness": "\ud83d\udd05", "sake": "\ud83c\udf76", "bow_and_arrow": "\ud83c\udff9", "cooking": "\ud83c\udf73", "fish_cake": "\ud83c\udf65", "tomato": "\ud83c\udf45", "couple_with_heart": "\ud83d\udc91", "telephone_receiver": "\ud83d\udcde", "triangular_flag_on_post": "\ud83d\udea9", "jack_o_lantern": "\ud83c\udf83", "blue_book": "\ud83d\udcd8", "clock530": "\ud83d\udd60", "u6709": "\ud83c\ude36", "palms_up_together": "\ud83e\udd32", "lion_face": "\ud83e\udd81", "lock": "\ud83d\udd12", "duck": "\ud83e\udd86", "truck": "\ud83d\ude9a", "oden": "\ud83c\udf62", "busts_in_silhouette": "\ud83d\udc65", "hourglass_flowing_sand": "\u23f3", "frog": "\ud83d\udc38", "fox": "\ud83e\udd8a", "bread": "\ud83c\udf5e", "put_litter_in_its_place": "\ud83d\udeae", "couple": "\ud83d\udc6b", "bamboo": "\ud83c\udf8d", "regional_indicator_c": "\ud83c\udde8", "menorah": "\ud83d\udd4e", "circus_tent": "\ud83c\udfaa", "lying_face": "\ud83e\udd25", "small_orange_diamond": "\ud83d\udd38", "ship": "\ud83d\udea2", "person_frowning": "\ud83d\ude4d", "racehorse": "\ud83d\udc0e", "thumbsup": "\ud83d\udc4d", "cupid": "\ud83d\udc98", "robot": "\ud83e\udd16", "fallen_leaf": "\ud83c\udf42", "pig_nose": "\ud83d\udc3d", "vibration_mode": "\ud83d\udcf3", "necktie": "\ud83d\udc54", "boy": "\ud83d\udc66", "house_with_garden": "\ud83c\udfe1", "point_down": "\ud83d\udc47", "grey_exclamation": "\u2755", "books": "\ud83d\udcda", "regional_indicator_k": "\ud83c\uddf0", "shirt": "\ud83d\udc55", "fries": "\ud83c\udf5f", "dart": "\ud83c\udfaf", "tea": "\ud83c\udf75", "mrs_claus": "\ud83e\udd36", "suspension_railway": "\ud83d\ude9f", "baby_symbol": "\ud83d\udebc", "sweet_potato": "\ud83c\udf60", "butterfly": "\ud83e\udd8b", "performing_arts": "\ud83c\udfad", "notebook": "\ud83d\udcd3", "bat": "\ud83e\udd87"} \ No newline at end of file diff --git a/priv/static/static/js/app.30c01d7540d43b760f03.js b/priv/static/static/js/app.30c01d7540d43b760f03.js new file mode 100644 index 000000000..60e8ac118 Binary files /dev/null and b/priv/static/static/js/app.30c01d7540d43b760f03.js differ diff --git a/priv/static/static/js/app.30c01d7540d43b760f03.js.map b/priv/static/static/js/app.30c01d7540d43b760f03.js.map new file mode 100644 index 000000000..5064f6398 Binary files /dev/null and b/priv/static/static/js/app.30c01d7540d43b760f03.js.map differ diff --git a/priv/static/static/js/app.fefccf252cac9e1310ea.js b/priv/static/static/js/app.fefccf252cac9e1310ea.js deleted file mode 100644 index 343f7503d..000000000 Binary files a/priv/static/static/js/app.fefccf252cac9e1310ea.js and /dev/null differ diff --git a/priv/static/static/js/app.fefccf252cac9e1310ea.js.map b/priv/static/static/js/app.fefccf252cac9e1310ea.js.map deleted file mode 100644 index b51ed9f3a..000000000 Binary files a/priv/static/static/js/app.fefccf252cac9e1310ea.js.map and /dev/null differ diff --git a/priv/static/static/js/manifest.15dfe939c498cca9840c.js b/priv/static/static/js/manifest.15dfe939c498cca9840c.js new file mode 100644 index 000000000..9cd39983a Binary files /dev/null and b/priv/static/static/js/manifest.15dfe939c498cca9840c.js differ diff --git a/priv/static/static/js/manifest.15dfe939c498cca9840c.js.map b/priv/static/static/js/manifest.15dfe939c498cca9840c.js.map new file mode 100644 index 000000000..116fca551 Binary files /dev/null and b/priv/static/static/js/manifest.15dfe939c498cca9840c.js.map differ diff --git a/priv/static/static/js/manifest.ee87253244897e08bdce.js b/priv/static/static/js/manifest.ee87253244897e08bdce.js deleted file mode 100644 index cf9d9c73d..000000000 Binary files a/priv/static/static/js/manifest.ee87253244897e08bdce.js and /dev/null differ diff --git a/priv/static/static/js/manifest.ee87253244897e08bdce.js.map b/priv/static/static/js/manifest.ee87253244897e08bdce.js.map deleted file mode 100644 index 97fcf42cf..000000000 Binary files a/priv/static/static/js/manifest.ee87253244897e08bdce.js.map and /dev/null differ diff --git a/priv/static/static/js/vendor.409059e5a814f448f5bc.js b/priv/static/static/js/vendor.409059e5a814f448f5bc.js new file mode 100644 index 000000000..1dae3910d Binary files /dev/null and b/priv/static/static/js/vendor.409059e5a814f448f5bc.js differ diff --git a/priv/static/static/js/vendor.409059e5a814f448f5bc.js.map b/priv/static/static/js/vendor.409059e5a814f448f5bc.js.map new file mode 100644 index 000000000..0fc735df4 Binary files /dev/null and b/priv/static/static/js/vendor.409059e5a814f448f5bc.js.map differ diff --git a/priv/static/static/js/vendor.50cd70f77f559bfe1f27.js b/priv/static/static/js/vendor.50cd70f77f559bfe1f27.js deleted file mode 100644 index 47efc7091..000000000 Binary files a/priv/static/static/js/vendor.50cd70f77f559bfe1f27.js and /dev/null differ diff --git a/priv/static/static/js/vendor.50cd70f77f559bfe1f27.js.map b/priv/static/static/js/vendor.50cd70f77f559bfe1f27.js.map deleted file mode 100644 index d23d16168..000000000 Binary files a/priv/static/static/js/vendor.50cd70f77f559bfe1f27.js.map and /dev/null differ diff --git a/test/notification_test.exs b/test/notification_test.exs index eee1c9fa3..0a4462241 100644 --- a/test/notification_test.exs +++ b/test/notification_test.exs @@ -14,9 +14,9 @@ test "notifies someone when they are directly addressed" do {:ok, [notification, other_notification]} = Notification.create_notifications(activity) - assert notification.user_id == other_user.id + notified_ids = Enum.sort([notification.user_id, other_notification.user_id]) + assert notified_ids == [other_user.id, third_user.id] assert notification.activity_id == activity.id - assert other_notification.user_id == third_user.id assert other_notification.activity_id == activity.id end end diff --git a/test/web/mastodon_api/account_view_test.exs b/test/web/mastodon_api/account_view_test.exs index eccfe0b36..5eefa61e1 100644 --- a/test/web/mastodon_api/account_view_test.exs +++ b/test/web/mastodon_api/account_view_test.exs @@ -19,10 +19,10 @@ test "Represent a user account" do statuses_count: 5, note: user.bio, url: user.ap_id, - avatar: "https://placehold.it/48x48", - avatar_static: "https://placehold.it/48x48", - header: "https://placehold.it/700x335", - header_static: "https://placehold.it/700x335", + avatar: "http://localhost:4001/images/avi.png", + avatar_static: "http://localhost:4001/images/avi.png", + header: "http://localhost:4001/images/banner.png", + header_static: "http://localhost:4001/images/banner.png", source: %{ note: "", privacy: "public", diff --git a/test/web/mastodon_api/mastodon_api_controller_test.exs b/test/web/mastodon_api/mastodon_api_controller_test.exs index fc0010569..93b29dfae 100644 --- a/test/web/mastodon_api/mastodon_api_controller_test.exs +++ b/test/web/mastodon_api/mastodon_api_controller_test.exs @@ -35,7 +35,7 @@ test "the public timeline", %{conn: conn} do {:ok, [_activity]} = OStatus.fetch_activity_from_url("https://shitposter.club/notice/2827873") conn = conn - |> get("/api/v1/timelines/public") + |> get("/api/v1/timelines/public", %{"local" => "False"}) assert length(json_response(conn, 200)) == 2 @@ -43,6 +43,11 @@ test "the public timeline", %{conn: conn} do |> get("/api/v1/timelines/public", %{"local" => "True"}) assert [%{"content" => "test"}] = json_response(conn, 200) + + conn = build_conn() + |> get("/api/v1/timelines/public", %{"local" => "1"}) + + assert [%{"content" => "test"}] = json_response(conn, 200) end test "posting a status", %{conn: conn} do @@ -50,9 +55,9 @@ test "posting a status", %{conn: conn} do conn = conn |> assign(:user, user) - |> post("/api/v1/statuses", %{"status" => "cofe", "spoiler_text" => "2hu"}) + |> post("/api/v1/statuses", %{"status" => "cofe", "spoiler_text" => "2hu", "sensitive" => "false"}) - assert %{"content" => "cofe", "id" => id, "spoiler_text" => "2hu"} = json_response(conn, 200) + assert %{"content" => "cofe", "id" => id, "spoiler_text" => "2hu", "sensitive" => false} = json_response(conn, 200) assert Repo.get(Activity, id) end @@ -145,7 +150,7 @@ test "list of notifications", %{conn: conn} do |> assign(:user, user) |> get("/api/v1/notifications") - expected_response = "hi @#{user.nickname}" + expected_response = "hi @#{user.nickname}" assert [%{"status" => %{"content" => response}} | _rest] = json_response(conn, 200) assert response == expected_response end @@ -161,7 +166,7 @@ test "getting a single notification", %{conn: conn} do |> assign(:user, user) |> get("/api/v1/notifications/#{notification.id}") - expected_response = "hi @#{user.nickname}" + expected_response = "hi @#{user.nickname}" assert %{"status" => %{"content" => response}} = json_response(conn, 200) assert response == expected_response end @@ -581,11 +586,14 @@ test "get instance information" do {:ok, _} = TwitterAPI.create_status(user, %{"status" => "cofe"}) + Pleroma.Stats.update_stats() + conn = conn |> get("/api/v1/instance") assert result = json_response(conn, 200) assert result["stats"]["user_count"] == 2 + assert result["stats"]["status_count"] == 1 end end diff --git a/test/web/mastodon_api/status_view_test.exs b/test/web/mastodon_api/status_view_test.exs index 93c0b7236..0d396f3b8 100644 --- a/test/web/mastodon_api/status_view_test.exs +++ b/test/web/mastodon_api/status_view_test.exs @@ -56,7 +56,9 @@ test "a note activity" do test "contains mentions" do incoming = File.read!("test/fixtures/incoming_reply_mastodon.xml") - user = insert(:user, %{ap_id: "https://pleroma.soykaf.com/users/lain"}) + # a user with this ap id might be in the cache. + recipient = "https://pleroma.soykaf.com/users/lain" + user = User.get_cached_by_ap_id(recipient) || insert(:user, %{ap_id: recipient}) {:ok, [activity]} = OStatus.handle_incoming(incoming) diff --git a/test/web/ostatus/feed_representer_test.exs b/test/web/ostatus/feed_representer_test.exs index df5a964e2..e10936366 100644 --- a/test/web/ostatus/feed_representer_test.exs +++ b/test/web/ostatus/feed_representer_test.exs @@ -26,6 +26,7 @@ test "returns a feed of the last 20 items of the user" do #{OStatus.feed_path(user)} #{user.nickname}'s timeline #{most_recent_update} + #{User.avatar_url(user)} diff --git a/test/web/ostatus/ostatus_test.exs b/test/web/ostatus/ostatus_test.exs index de01612b3..b27f8cb55 100644 --- a/test/web/ostatus/ostatus_test.exs +++ b/test/web/ostatus/ostatus_test.exs @@ -302,7 +302,8 @@ test "it returns user info in a hash" do "host" => "social.heldscal.la", "fqn" => user, "bio" => "cofe", - "avatar" => %{"type" => "Image", "url" => [%{"href" => "https://social.heldscal.la/avatar/29191-original-20170421154949.jpeg", "mediaType" => "image/jpeg", "type" => "Link"}]} + "avatar" => %{"type" => "Image", "url" => [%{"href" => "https://social.heldscal.la/avatar/29191-original-20170421154949.jpeg", "mediaType" => "image/jpeg", "type" => "Link"}]}, + "subscribe_address" => "https://social.heldscal.la/main/ostatussub?profile={uri}" } assert data == expected end @@ -325,7 +326,8 @@ test "it works with the uri" do "host" => "social.heldscal.la", "fqn" => user, "bio" => "cofe", - "avatar" => %{"type" => "Image", "url" => [%{"href" => "https://social.heldscal.la/avatar/29191-original-20170421154949.jpeg", "mediaType" => "image/jpeg", "type" => "Link"}]} + "avatar" => %{"type" => "Image", "url" => [%{"href" => "https://social.heldscal.la/avatar/29191-original-20170421154949.jpeg", "mediaType" => "image/jpeg", "type" => "Link"}]}, + "subscribe_address" => "https://social.heldscal.la/main/ostatussub?profile={uri}" } assert data == expected end diff --git a/test/web/ostatus/user_representer_test.exs b/test/web/ostatus/user_representer_test.exs index d5d70f5c6..b22420379 100644 --- a/test/web/ostatus/user_representer_test.exs +++ b/test/web/ostatus/user_representer_test.exs @@ -21,6 +21,7 @@ test "returns a user with id, uri, name and link" do #{user.bio} #{user.nickname} + """ assert clean(res) == clean(expected) diff --git a/test/web/twitter_api/twitter_api_controller_test.exs b/test/web/twitter_api/twitter_api_controller_test.exs index 90d0fa654..39f1cdd4c 100644 --- a/test/web/twitter_api/twitter_api_controller_test.exs +++ b/test/web/twitter_api/twitter_api_controller_test.exs @@ -518,7 +518,7 @@ test "it returns a user's followers", %{conn: conn} do end describe "GET /api/statuses/friends" do - test "it returns a user's friends", %{conn: conn} do + test "it returns the logged in user's friends", %{conn: conn} do user = insert(:user) followed_one = insert(:user) followed_two = insert(:user) @@ -533,6 +533,36 @@ test "it returns a user's friends", %{conn: conn} do assert MapSet.equal?(MapSet.new(json_response(conn, 200)), MapSet.new(UserView.render("index.json", %{users: [followed_one, followed_two], for: user}))) end + + test "it returns a given user's friends with user_id", %{conn: conn} do + user = insert(:user) + followed_one = insert(:user) + followed_two = insert(:user) + not_followed = insert(:user) + + {:ok, user} = User.follow(user, followed_one) + {:ok, user} = User.follow(user, followed_two) + + conn = conn + |> get("/api/statuses/friends", %{"user_id" => user.id}) + + assert MapSet.equal?(MapSet.new(json_response(conn, 200)), MapSet.new(UserView.render("index.json", %{users: [followed_one, followed_two], for: user}))) + end + + test "it returns a given user's friends with screen_name", %{conn: conn} do + user = insert(:user) + followed_one = insert(:user) + followed_two = insert(:user) + not_followed = insert(:user) + + {:ok, user} = User.follow(user, followed_one) + {:ok, user} = User.follow(user, followed_two) + + conn = conn + |> get("/api/statuses/friends", %{"screen_name" => user.nickname}) + + assert MapSet.equal?(MapSet.new(json_response(conn, 200)), MapSet.new(UserView.render("index.json", %{users: [followed_one, followed_two], for: user}))) + end end describe "GET /friends/ids" do diff --git a/test/web/twitter_api/twitter_api_test.exs b/test/web/twitter_api/twitter_api_test.exs index 96552f97e..ac62880d5 100644 --- a/test/web/twitter_api/twitter_api_test.exs +++ b/test/web/twitter_api/twitter_api_test.exs @@ -34,7 +34,7 @@ test "create a status" do { :ok, activity = %Activity{} } = TwitterAPI.create_status(user, input) - assert get_in(activity.data, ["object", "content"]) == "Hello again, @shp.<script></script>
This is on another :moominmamma: line. #2hu #epic #phantasmagoric
image.jpg" + assert get_in(activity.data, ["object", "content"]) == "Hello again, @shp.<script></script>
This is on another :moominmamma: line. #2hu #epic #phantasmagoric
image.jpg" assert get_in(activity.data, ["object", "type"]) == "Note" assert get_in(activity.data, ["object", "actor"]) == user.ap_id assert get_in(activity.data, ["actor"]) == user.ap_id @@ -291,7 +291,7 @@ test "it adds user links to an existing text" do archaeme_remote = insert(:user, %{nickname: "archaeme@archae.me"}) mentions = Pleroma.Formatter.parse_mentions(text) - expected_text = "@gsimg According to @archaeme, that is @daggsy. Also hello @archaeme" + expected_text = "@gsimg According to @archaeme, that is @daggsy. Also hello @archaeme" assert Utils.add_user_links(text, mentions) == expected_text end @@ -404,7 +404,7 @@ test "fetches a user by uri" do assert represented["id"] == UserView.render("show.json", %{user: remote, for: user})["id"] # Also fetches the feed. - assert Activity.get_create_activity_by_object_ap_id("tag:mastodon.social,2017-04-05:objectId=1641750:objectType=Status") + # assert Activity.get_create_activity_by_object_ap_id("tag:mastodon.social,2017-04-05:objectId=1641750:objectType=Status") end end end diff --git a/test/web/twitter_api/views/user_view_test.exs b/test/web/twitter_api/views/user_view_test.exs index 18a19ef70..d5d2f0adc 100644 --- a/test/web/twitter_api/views/user_view_test.exs +++ b/test/web/twitter_api/views/user_view_test.exs @@ -30,10 +30,11 @@ test "A user" do User.follow(follower, user) User.follow(second_follower, user) User.follow(user, follower) + {:ok, user} = User.update_follower_count(user) + Cachex.set(:user_cache, "user_info:#{user.id}", User.user_info(Repo.get!(User, user.id))) - user = Repo.get!(User, user.id) - - image = "https://placehold.it/48x48" + image = "http://localhost:4001/images/avi.png" + banner = "http://localhost:4001/images/banner.png" represented = %{ "id" => user.id, @@ -54,8 +55,9 @@ test "A user" do "statusnet_blocking" => false, "rights" => %{}, "statusnet_profile_url" => user.ap_id, - "cover_photo" => nil, - "background_image" => nil + "cover_photo" => banner, + "background_image" => nil, + "is_local" => true } assert represented == UserView.render("show.json", %{user: user}) @@ -64,7 +66,9 @@ test "A user" do test "A user for a given other follower", %{user: user} do {:ok, follower} = UserBuilder.insert(%{following: [User.ap_followers(user)]}) {:ok, user} = User.update_follower_count(user) - image = "https://placehold.it/48x48" + image = "http://localhost:4001/images/avi.png" + banner = "http://localhost:4001/images/banner.png" + represented = %{ "id" => user.id, "name" => user.name, @@ -84,8 +88,9 @@ test "A user for a given other follower", %{user: user} do "statusnet_blocking" => false, "rights" => %{}, "statusnet_profile_url" => user.ap_id, - "cover_photo" => nil, - "background_image" => nil + "cover_photo" => banner, + "background_image" => nil, + "is_local" => true } assert represented == UserView.render("show.json", %{user: user, for: follower}) @@ -95,7 +100,9 @@ test "A user that follows you", %{user: user} do follower = insert(:user) {:ok, follower} = User.follow(follower, user) {:ok, user} = User.update_follower_count(user) - image = "https://placehold.it/48x48" + image = "http://localhost:4001/images/avi.png" + banner = "http://localhost:4001/images/banner.png" + represented = %{ "id" => follower.id, "name" => follower.name, @@ -115,8 +122,9 @@ test "A user that follows you", %{user: user} do "statusnet_blocking" => false, "rights" => %{}, "statusnet_profile_url" => follower.ap_id, - "cover_photo" => nil, - "background_image" => nil + "cover_photo" => banner, + "background_image" => nil, + "is_local" => true } assert represented == UserView.render("show.json", %{user: follower, for: user}) @@ -126,7 +134,9 @@ test "A blocked user for the blocker", %{user: user} do user = insert(:user) blocker = insert(:user) User.block(blocker, user) - image = "https://placehold.it/48x48" + image = "http://localhost:4001/images/avi.png" + banner = "http://localhost:4001/images/banner.png" + represented = %{ "id" => user.id, "name" => user.name, @@ -146,8 +156,9 @@ test "A blocked user for the blocker", %{user: user} do "statusnet_blocking" => true, "rights" => %{}, "statusnet_profile_url" => user.ap_id, - "cover_photo" => nil, - "background_image" => nil + "cover_photo" => banner, + "background_image" => nil, + "is_local" => true } blocker = Repo.get(User, blocker.id)