mirror of
https://github.com/ClaperCo/Claper.git
synced 2025-12-28 16:06:36 +01:00
Pin messages sent by attendees (#62)
This commit is contained in:
2
.tool-versions
Normal file
2
.tool-versions
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
erlang 26.1.2
|
||||||
|
elixir 1.15.7-otp-26
|
||||||
@@ -35,12 +35,19 @@ export class Presenter {
|
|||||||
if (data.value) {
|
if (data.value) {
|
||||||
document.getElementById("post-list").classList.remove("animate__animated", "animate__fadeOutLeft")
|
document.getElementById("post-list").classList.remove("animate__animated", "animate__fadeOutLeft")
|
||||||
document.getElementById("post-list").classList.add("animate__animated", "animate__fadeInLeft")
|
document.getElementById("post-list").classList.add("animate__animated", "animate__fadeInLeft")
|
||||||
|
|
||||||
|
document.getElementById("pinned-post-list").classList.remove("animate__animated", "animate__fadeOutLeft")
|
||||||
|
document.getElementById("pinned-post-list").classList.add("animate__animated", "animate__fadeInLeft")
|
||||||
} else {
|
} else {
|
||||||
document.getElementById("post-list").classList.remove("animate__animated", "animate__fadeInLeft")
|
document.getElementById("post-list").classList.remove("animate__animated", "animate__fadeInLeft")
|
||||||
document.getElementById("post-list").classList.add("animate__animated", "animate__fadeOutLeft")
|
document.getElementById("post-list").classList.add("animate__animated", "animate__fadeOutLeft")
|
||||||
|
|
||||||
|
document.getElementById("pinned-post-list").classList.remove("animate__animated", "animate__fadeInLeft")
|
||||||
|
document.getElementById("pinned-post-list").classList.add("animate__animated", "animate__fadeOutLeft")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
this.context.handleEvent('poll-visible', data => {
|
this.context.handleEvent('poll-visible', data => {
|
||||||
if (data.value) {
|
if (data.value) {
|
||||||
document.getElementById("poll").classList.remove("animate__animated", "animate__fadeOut")
|
document.getElementById("poll").classList.remove("animate__animated", "animate__fadeOut")
|
||||||
|
|||||||
1557
assets/package-lock.json
generated
1557
assets/package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -5,7 +5,7 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"alpinejs": "^3.13.1",
|
"alpinejs": "^3.13.1",
|
||||||
"autoprefixer": "^10.4.15",
|
"autoprefixer": "^10.4.15",
|
||||||
"esbuild": "^0.14.14",
|
"esbuild": "^0.14.54",
|
||||||
"flatpickr": "^4.6.13",
|
"flatpickr": "^4.6.13",
|
||||||
"postcss": "^8.4.29",
|
"postcss": "^8.4.29",
|
||||||
"postcss-import": "^15.1.0",
|
"postcss-import": "^15.1.0",
|
||||||
|
|||||||
@@ -24,6 +24,38 @@ defmodule Claper.Posts do
|
|||||||
|> Repo.preload(preload)
|
|> Repo.preload(preload)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get only the pinned event posts.
|
||||||
|
"""
|
||||||
|
def list_pinned_posts(event_id, preload \\ []) do
|
||||||
|
from(p in Post,
|
||||||
|
join: e in Claper.Events.Event,
|
||||||
|
on: p.event_id == e.id,
|
||||||
|
select: p,
|
||||||
|
# Only pinned posts
|
||||||
|
where: e.uuid == ^event_id and p.pinned == true,
|
||||||
|
order_by: [asc: p.id]
|
||||||
|
)
|
||||||
|
|> Repo.all()
|
||||||
|
|> Repo.preload(preload)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Get only the unpinned event posts.
|
||||||
|
"""
|
||||||
|
def list_unpinned_posts(event_id, preload \\ []) do
|
||||||
|
from(p in Post,
|
||||||
|
join: e in Claper.Events.Event,
|
||||||
|
on: p.event_id == e.id,
|
||||||
|
select: p,
|
||||||
|
# Only unpinned posts
|
||||||
|
where: e.uuid == ^event_id and p.pinned == false,
|
||||||
|
order_by: [asc: p.id]
|
||||||
|
)
|
||||||
|
|> Repo.all()
|
||||||
|
|> Repo.preload(preload)
|
||||||
|
end
|
||||||
|
|
||||||
def reacted_posts(event_id, user_id, icon) when is_number(user_id) do
|
def reacted_posts(event_id, user_id, icon) when is_number(user_id) do
|
||||||
from(reaction in Claper.Posts.Reaction,
|
from(reaction in Claper.Posts.Reaction,
|
||||||
join: post in Claper.Posts.Post,
|
join: post in Claper.Posts.Post,
|
||||||
@@ -99,10 +131,41 @@ defmodule Claper.Posts do
|
|||||||
|
|
||||||
"""
|
"""
|
||||||
def update_post(%Post{} = post, attrs) do
|
def update_post(%Post{} = post, attrs) do
|
||||||
post
|
changeset = Post.changeset(post, attrs)
|
||||||
|> Post.changeset(attrs)
|
|
||||||
|> Repo.update()
|
result = changeset |> Repo.update()
|
||||||
|> broadcast(:post_updated)
|
|
||||||
|
result |> broadcast(:post_updated)
|
||||||
|
end
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Pins or unpins a post based on its current state.
|
||||||
|
|
||||||
|
## Examples
|
||||||
|
|
||||||
|
iex> toggle_pin_post(post)
|
||||||
|
{:ok, %Post{}}
|
||||||
|
|
||||||
|
iex> toggle_pin_post(invalid_post)
|
||||||
|
{:error, %Ecto.Changeset{}}
|
||||||
|
|
||||||
|
"""
|
||||||
|
def toggle_pin_post(%Post{} = post) do
|
||||||
|
# Toggling the pinned state
|
||||||
|
new_pinned_state = not post.pinned
|
||||||
|
changeset = Post.changeset(post, %{pinned: new_pinned_state})
|
||||||
|
|
||||||
|
result = changeset |> Repo.update()
|
||||||
|
|
||||||
|
# Broadcast the appropriate message based on the new state
|
||||||
|
broadcast_message =
|
||||||
|
if new_pinned_state do
|
||||||
|
:post_pinned
|
||||||
|
else
|
||||||
|
:post_unpinned
|
||||||
|
end
|
||||||
|
|
||||||
|
result |> broadcast(broadcast_message)
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ defmodule Claper.Posts.Post do
|
|||||||
field :name, :string
|
field :name, :string
|
||||||
field :attendee_identifier, :string
|
field :attendee_identifier, :string
|
||||||
field :position, :integer, default: 0
|
field :position, :integer, default: 0
|
||||||
|
field :pinned, :boolean, default: false
|
||||||
|
|
||||||
belongs_to :event, Claper.Events.Event
|
belongs_to :event, Claper.Events.Event
|
||||||
belongs_to :user, Claper.Accounts.User
|
belongs_to :user, Claper.Accounts.User
|
||||||
@@ -30,7 +31,8 @@ defmodule Claper.Posts.Post do
|
|||||||
:love_count,
|
:love_count,
|
||||||
:lol_count,
|
:lol_count,
|
||||||
:name,
|
:name,
|
||||||
:position
|
:position,
|
||||||
|
:pinned
|
||||||
])
|
])
|
||||||
|> validate_required([:body, :position])
|
|> validate_required([:body, :position])
|
||||||
|> validate_length(:body, min: 2, max: 255)
|
|> validate_length(:body, min: 2, max: 255)
|
||||||
|
|||||||
@@ -10,6 +10,7 @@ defmodule Claper.Presentations.PresentationState do
|
|||||||
field :chat_enabled, :boolean
|
field :chat_enabled, :boolean
|
||||||
field :anonymous_chat_enabled, :boolean
|
field :anonymous_chat_enabled, :boolean
|
||||||
field :banned, {:array, :string}, default: []
|
field :banned, {:array, :string}, default: []
|
||||||
|
field :show_only_pinned, :boolean, default: false
|
||||||
|
|
||||||
belongs_to :presentation_file, Claper.Presentations.PresentationFile
|
belongs_to :presentation_file, Claper.Presentations.PresentationFile
|
||||||
|
|
||||||
@@ -27,7 +28,8 @@ defmodule Claper.Presentations.PresentationState do
|
|||||||
:banned,
|
:banned,
|
||||||
:presentation_file_id,
|
:presentation_file_id,
|
||||||
:chat_enabled,
|
:chat_enabled,
|
||||||
:anonymous_chat_enabled
|
:anonymous_chat_enabled,
|
||||||
|
:show_only_pinned
|
||||||
])
|
])
|
||||||
|> validate_required([])
|
|> validate_required([])
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -41,7 +41,8 @@ defmodule ClaperWeb.EventLive.Manage do
|
|||||||
|> assign(:attendees_nb, 1)
|
|> assign(:attendees_nb, 1)
|
||||||
|> assign(:event, event)
|
|> assign(:event, event)
|
||||||
|> assign(:state, event.presentation_file.presentation_state)
|
|> assign(:state, event.presentation_file.presentation_state)
|
||||||
|> assign(:posts, list_posts(socket, event.uuid))
|
|> assign(:pinned_posts, list_pinned_posts(socket, event.uuid))
|
||||||
|
|> assign(:all_posts, list_all_posts(socket, event.uuid))
|
||||||
|> assign(:polls, list_polls(socket, event.presentation_file.id))
|
|> assign(:polls, list_polls(socket, event.presentation_file.id))
|
||||||
|> assign(:forms, list_forms(socket, event.presentation_file.id))
|
|> assign(:forms, list_forms(socket, event.presentation_file.id))
|
||||||
|> assign(:embeds, list_embeds(socket, event.presentation_file.id))
|
|> assign(:embeds, list_embeds(socket, event.presentation_file.id))
|
||||||
@@ -60,6 +61,16 @@ defmodule ClaperWeb.EventLive.Manage do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp delete_post_from_list(posts, deleted_post) do
|
||||||
|
Enum.reject(posts, fn post -> post.id == deleted_post.id end)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp update_post_in_list(posts, updated_post) do
|
||||||
|
Enum.map(posts, fn post ->
|
||||||
|
if post.id == updated_post.id, do: updated_post, else: post
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
defp is_leader(%{assigns: %{current_user: current_user}} = _socket, event) do
|
defp is_leader(%{assigns: %{current_user: current_user}} = _socket, event) do
|
||||||
Claper.Events.is_leaded_by(current_user.email, event) || event.user.id == current_user.id
|
Claper.Events.is_leaded_by(current_user.email, event) || event.user.id == current_user.id
|
||||||
end
|
end
|
||||||
@@ -75,27 +86,50 @@ defmodule ClaperWeb.EventLive.Manage do
|
|||||||
@impl true
|
@impl true
|
||||||
def handle_info({:post_created, post}, socket) do
|
def handle_info({:post_created, post}, socket) do
|
||||||
{:noreply,
|
{:noreply,
|
||||||
socket |> update(:posts, fn posts -> [post | posts] end) |> push_event("scroll", %{})}
|
socket
|
||||||
|
|> assign(:all_posts, [post | socket.assigns.all_posts])
|
||||||
|
|> push_event("scroll", %{})}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_info({:post_updated, post}, socket) do
|
def handle_info({:post_updated, updated_post}, socket) do
|
||||||
{:noreply, socket |> update(:posts, fn posts -> [post | posts] end)}
|
updated_posts = update_post_in_list(socket.assigns.all_posts, updated_post)
|
||||||
|
updated_pinned_posts = update_post_in_list(socket.assigns.pinned_posts, updated_post)
|
||||||
|
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> assign(:all_posts, updated_posts)
|
||||||
|
|> assign(:pinned_posts, updated_pinned_posts)}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_info({:reaction_added, post}, socket) do
|
def handle_info({:post_deleted, deleted_post}, socket) do
|
||||||
{:noreply, socket |> update(:posts, fn posts -> [post | posts] end)}
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> update(:all_posts, fn posts -> [deleted_post | posts] end)
|
||||||
|
|> update(:pinned_posts, fn pinned_posts ->
|
||||||
|
delete_post_from_list(pinned_posts, deleted_post)
|
||||||
|
end)}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_info({:reaction_removed, post}, socket) do
|
def handle_info({:post_pinned, _post}, socket) do
|
||||||
{:noreply, socket |> update(:posts, fn posts -> [post | posts] end)}
|
updated_socket =
|
||||||
|
socket
|
||||||
|
|> update(:all_posts, fn _all_posts -> socket.assigns.all_posts end)
|
||||||
|
|> update(:pinned_posts, fn _pinned_posts -> socket.assigns.pinned_posts end)
|
||||||
|
|
||||||
|
{:noreply, updated_socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_info({:post_deleted, post}, socket) do
|
def handle_info({:post_unpinned, _post}, socket) do
|
||||||
{:noreply, socket |> update(:posts, fn posts -> [post | posts] end)}
|
updated_socket =
|
||||||
|
socket
|
||||||
|
|> update(:all_posts, fn _all_posts -> socket.assigns.all_posts end)
|
||||||
|
|> update(:pinned_posts, fn _pinned_posts -> socket.assigns.pinned_posts end)
|
||||||
|
|
||||||
|
{:noreply, updated_socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
@@ -386,6 +420,12 @@ defmodule ClaperWeb.EventLive.Manage do
|
|||||||
ban(attendee_identifier, socket)
|
ban(attendee_identifier, socket)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_event("pin", %{"id" => id}, socket) do
|
||||||
|
post = Claper.Posts.get_post!(id, [:event])
|
||||||
|
pin(post, socket)
|
||||||
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_event(
|
def handle_event(
|
||||||
"ban",
|
"ban",
|
||||||
@@ -465,6 +505,23 @@ defmodule ClaperWeb.EventLive.Manage do
|
|||||||
{:noreply, socket |> assign(:state, new_state)}
|
{:noreply, socket |> assign(:state, new_state)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_event(
|
||||||
|
"checked",
|
||||||
|
%{"key" => "show_only_pinned", "value" => value},
|
||||||
|
%{assigns: %{event: _event, state: state}} = socket
|
||||||
|
) do
|
||||||
|
{:ok, new_state} =
|
||||||
|
Claper.Presentations.update_presentation_state(
|
||||||
|
state,
|
||||||
|
%{
|
||||||
|
:show_only_pinned => value
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|
||||||
|
{:noreply, socket |> assign(:state, new_state)}
|
||||||
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_event(
|
def handle_event(
|
||||||
"checked",
|
"checked",
|
||||||
@@ -483,11 +540,19 @@ defmodule ClaperWeb.EventLive.Manage do
|
|||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_event("delete", %{"event-id" => event_id, "id" => id}, socket) do
|
def handle_event("delete", %{"id" => id}, socket) do
|
||||||
post = Claper.Posts.get_post!(id, [:event])
|
post = Claper.Posts.get_post!(id, [:event])
|
||||||
{:ok, _} = Claper.Posts.delete_post(post)
|
{:ok, _} = Claper.Posts.delete_post(post)
|
||||||
|
|
||||||
{:noreply, assign(socket, :posts, list_posts(socket, event_id))}
|
updated_socket =
|
||||||
|
if post.pinned do
|
||||||
|
assign(socket, :pinned_posts, list_pinned_posts(socket, socket.assigns.event.uuid))
|
||||||
|
assign(socket, :all_posts, list_all_posts(socket, socket.assigns.event.uuid))
|
||||||
|
else
|
||||||
|
assign(socket, :all_posts, list_all_posts(socket, socket.assigns.event.uuid))
|
||||||
|
end
|
||||||
|
|
||||||
|
{:noreply, updated_socket}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
@@ -510,7 +575,9 @@ defmodule ClaperWeb.EventLive.Manage do
|
|||||||
socket =
|
socket =
|
||||||
case tab do
|
case tab do
|
||||||
"posts" ->
|
"posts" ->
|
||||||
assign(socket, :posts, list_posts(socket, socket.assigns.event.uuid))
|
socket
|
||||||
|
|> assign(:pinned_posts, list_pinned_posts(socket, socket.assigns.event.uuid))
|
||||||
|
|> assign(:all_posts, list_all_posts(socket, socket.assigns.event.uuid))
|
||||||
|
|
||||||
"forms" ->
|
"forms" ->
|
||||||
assign(
|
assign(
|
||||||
@@ -518,6 +585,12 @@ defmodule ClaperWeb.EventLive.Manage do
|
|||||||
:form_submits,
|
:form_submits,
|
||||||
list_form_submits(socket, socket.assigns.event.presentation_file.id)
|
list_form_submits(socket, socket.assigns.event.presentation_file.id)
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
"pinned_posts" ->
|
||||||
|
socket
|
||||||
|
|> assign(:pinned_posts, list_pinned_posts(socket, socket.assigns.event.uuid))
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
||||||
{:noreply, socket}
|
{:noreply, socket}
|
||||||
@@ -663,6 +736,17 @@ defmodule ClaperWeb.EventLive.Manage do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp pin(post, socket) do
|
||||||
|
{:ok, _updated_post} = Claper.Posts.toggle_pin_post(post)
|
||||||
|
|
||||||
|
updated_socket =
|
||||||
|
socket
|
||||||
|
|> assign(:all_posts, list_all_posts(socket, socket.assigns.event.uuid))
|
||||||
|
|> assign(:pinned_posts, list_pinned_posts(socket, socket.assigns.event.uuid))
|
||||||
|
|
||||||
|
{:noreply, updated_socket}
|
||||||
|
end
|
||||||
|
|
||||||
defp embed_at_position(
|
defp embed_at_position(
|
||||||
%{assigns: %{event: event, state: state}} = socket,
|
%{assigns: %{event: event, state: state}} = socket,
|
||||||
broadcast \\ true
|
broadcast \\ true
|
||||||
@@ -699,7 +783,11 @@ defmodule ClaperWeb.EventLive.Manage do
|
|||||||
{:noreply, socket |> assign(:state, new_state)}
|
{:noreply, socket |> assign(:state, new_state)}
|
||||||
end
|
end
|
||||||
|
|
||||||
defp list_posts(_socket, event_id) do
|
defp list_pinned_posts(_socket, event_id) do
|
||||||
|
Claper.Posts.list_pinned_posts(event_id, [:event, :reactions])
|
||||||
|
end
|
||||||
|
|
||||||
|
defp list_all_posts(_socket, event_id) do
|
||||||
Claper.Posts.list_posts(event_id, [:event, :reactions])
|
Claper.Posts.list_posts(event_id, [:event, :reactions])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
<div
|
<div
|
||||||
id="manager"
|
id="manager"
|
||||||
class="h-screen max-h-screen flex flex-col"
|
class="h-screen max-h-screen flex flex-col"
|
||||||
x-data={"{date: moment.utc('#{@event.expired_at}').local().format('lll')}"}
|
x-data={"{date:
|
||||||
|
moment.utc('#{@event.expired_at}').local().format('lll')}"}
|
||||||
phx-hook="Manager"
|
phx-hook="Manager"
|
||||||
data-max-page={@event.presentation_file.length}
|
data-max-page={@event.presentation_file.length}
|
||||||
data-current-page={@state.position}
|
data-current-page={@state.position}
|
||||||
@@ -117,7 +118,8 @@
|
|||||||
|
|
||||||
<div
|
<div
|
||||||
id="add-modal"
|
id="add-modal"
|
||||||
class={"#{if !@create, do: 'hidden'} fixed z-30 inset-0 overflow-y-auto p-4 sm:p-6 md:p-24 transform transition-all duration-150"}
|
class={"#{if !@create, do: 'hidden' } fixed z-30 inset-0 overflow-y-auto p-4 sm:p-6 md:p-24
|
||||||
|
transform transition-all duration-150"}
|
||||||
role="dialog"
|
role="dialog"
|
||||||
aria-modal="true"
|
aria-modal="true"
|
||||||
>
|
>
|
||||||
@@ -145,7 +147,7 @@
|
|||||||
</button>
|
</button>
|
||||||
|
|
||||||
<div id="modal-content" class="bg-gray-100">
|
<div id="modal-content" class="bg-gray-100">
|
||||||
<%= if @create == nil do %>
|
<%= if @create==nil do %>
|
||||||
<ul class="scroll-py-3 overflow-y-auto p-3" id="options" role="listbox">
|
<ul class="scroll-py-3 overflow-y-auto p-3" id="options" role="listbox">
|
||||||
<li id="option-1" role="option" tabindex="-1">
|
<li id="option-1" role="option" tabindex="-1">
|
||||||
<a
|
<a
|
||||||
@@ -171,7 +173,9 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4 flex-auto text-left">
|
<div class="ml-4 flex-auto text-left">
|
||||||
<p class="font-medium text-gray-700"><%= gettext("Poll") %></p>
|
<p class="font-medium text-gray-700">
|
||||||
|
<%= gettext("Poll") %>
|
||||||
|
</p>
|
||||||
<p class="text-gray-500">
|
<p class="text-gray-500">
|
||||||
<%= gettext("Add poll to know opinion of your public.") %>
|
<%= gettext("Add poll to know opinion of your public.") %>
|
||||||
</p>
|
</p>
|
||||||
@@ -208,7 +212,9 @@
|
|||||||
</svg>
|
</svg>
|
||||||
</div>
|
</div>
|
||||||
<div class="ml-4 flex-auto text-left">
|
<div class="ml-4 flex-auto text-left">
|
||||||
<p class="font-medium text-gray-700"><%= gettext("Form") %></p>
|
<p class="font-medium text-gray-700">
|
||||||
|
<%= gettext("Form") %>
|
||||||
|
</p>
|
||||||
<p class="text-gray-500">
|
<p class="text-gray-500">
|
||||||
<%= gettext("Add form to collect data from your public.") %>
|
<%= gettext("Add form to collect data from your public.") %>
|
||||||
</p>
|
</p>
|
||||||
@@ -248,7 +254,7 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
|
||||||
<%= if (length @polls) == 0 && (length @forms) == 0 do %>
|
<%= if (length @polls)==0 && (length @forms)==0 do %>
|
||||||
<div class="mt-10">
|
<div class="mt-10">
|
||||||
<a
|
<a
|
||||||
data-phx-link="patch"
|
data-phx-link="patch"
|
||||||
@@ -279,7 +285,7 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= if @create == "poll" do %>
|
<%= if @create=="poll" do %>
|
||||||
<div class="scroll-py-3 overflow-y-auto bg-gray-100 p-3">
|
<div class="scroll-py-3 overflow-y-auto bg-gray-100 p-3">
|
||||||
<p class="text-xl font-bold">
|
<p class="text-xl font-bold">
|
||||||
<%= case @create_action do
|
<%= case @create_action do
|
||||||
@@ -300,7 +306,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<%= if @create == "form" do %>
|
<%= if @create=="form" do %>
|
||||||
<div class="scroll-py-3 overflow-y-auto bg-gray-100 p-3">
|
<div class="scroll-py-3 overflow-y-auto bg-gray-100 p-3">
|
||||||
<p class="text-xl font-bold">
|
<p class="text-xl font-bold">
|
||||||
<%= case @create_action do
|
<%= case @create_action do
|
||||||
@@ -344,7 +350,9 @@
|
|||||||
|
|
||||||
<%= if @create == "import" do %>
|
<%= if @create == "import" do %>
|
||||||
<div class="scroll-py-3 overflow-y-auto bg-gray-100 p-3">
|
<div class="scroll-py-3 overflow-y-auto bg-gray-100 p-3">
|
||||||
<p class="text-xl font-bold"><%= gettext("Select presentation") %></p>
|
<p class="text-xl font-bold">
|
||||||
|
<%= gettext("Select presentation") %>
|
||||||
|
</p>
|
||||||
<ul>
|
<ul>
|
||||||
<%= for event <- @events do %>
|
<%= for event <- @events do %>
|
||||||
<li class="my-3">
|
<li class="my-3">
|
||||||
@@ -367,7 +375,9 @@
|
|||||||
d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3"
|
d="M3 16.5v2.25A2.25 2.25 0 005.25 21h13.5A2.25 2.25 0 0021 18.75V16.5M16.5 12L12 16.5m0 0L7.5 12m4.5 4.5V3"
|
||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
<span><%= event.name %></span>
|
<span>
|
||||||
|
<%= event.name %>
|
||||||
|
</span>
|
||||||
</button>
|
</button>
|
||||||
</li>
|
</li>
|
||||||
<% end %>
|
<% end %>
|
||||||
@@ -382,7 +392,7 @@
|
|||||||
<div class="bg-gray-100 pb-10 md:col-span-2 overflow-y-auto">
|
<div class="bg-gray-100 pb-10 md:col-span-2 overflow-y-auto">
|
||||||
<div class="flex flex-col justify-center items-center text-center">
|
<div class="flex flex-col justify-center items-center text-center">
|
||||||
<%= for index <- 0..@event.presentation_file.length-1 do %>
|
<%= for index <- 0..@event.presentation_file.length-1 do %>
|
||||||
<%= if @state.position == index && @state.position > 0 do %>
|
<%= if @state.position==index && @state.position> 0 do %>
|
||||||
<button
|
<button
|
||||||
phx-click="current-page"
|
phx-click="current-page"
|
||||||
phx-value-page={index - 1}
|
phx-value-page={index - 1}
|
||||||
@@ -402,7 +412,8 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<div
|
<div
|
||||||
class={"#{if @state.position == index, do: 'shadow-xl bg-white', else: 'opacity-50 bg-gray-100'} transition-all pb-5"}
|
class={"#{if @state.position==index, do: 'shadow-xl bg-white' , else: 'opacity-50 bg-gray-100' }
|
||||||
|
transition-all pb-5"}
|
||||||
id={"slide-preview-#{index}"}
|
id={"slide-preview-#{index}"}
|
||||||
>
|
>
|
||||||
<button
|
<button
|
||||||
@@ -418,7 +429,9 @@
|
|||||||
<% else %>
|
<% else %>
|
||||||
<img
|
<img
|
||||||
class="w-1/3 mx-auto"
|
class="w-1/3 mx-auto"
|
||||||
src={"https://#{Application.get_env(:claper, :presentations) |> Keyword.get(:aws_bucket)}.s3.#{Application.get_env(:ex_aws, :region)}.amazonaws.com/presentations/#{@event.presentation_file.hash}/#{index+1}.jpg"}
|
src={"https://#{Application.get_env(:claper, :presentations) |>
|
||||||
|
Keyword.get(:aws_bucket)}.s3.#{Application.get_env(:ex_aws,
|
||||||
|
:region)}.amazonaws.com/presentations/#{@event.presentation_file.hash}/#{index+1}.jpg"}
|
||||||
/>
|
/>
|
||||||
<% end %>
|
<% end %>
|
||||||
</button>
|
</button>
|
||||||
@@ -444,9 +457,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex space-x-2">
|
<div class="flex space-x-2">
|
||||||
<span>
|
<span>
|
||||||
<span class="font-semibold"><%= gettext "Poll" %></span>: <%= poll.title %>
|
<span class="font-semibold">
|
||||||
|
<%= gettext "Poll" %>
|
||||||
|
</span>: <%= poll.title %>
|
||||||
</span>
|
</span>
|
||||||
<%= if @state.position == index do %>
|
<%= if @state.position==index do %>
|
||||||
<%= if poll.enabled do %>
|
<%= if poll.enabled do %>
|
||||||
<button
|
<button
|
||||||
phx-click="poll-set-inactive"
|
phx-click="poll-set-inactive"
|
||||||
@@ -524,9 +539,11 @@
|
|||||||
</div>
|
</div>
|
||||||
<div class="flex space-x-2">
|
<div class="flex space-x-2">
|
||||||
<span>
|
<span>
|
||||||
<span class="font-semibold"><%= gettext "Form" %></span>: <%= form.title %>
|
<span class="font-semibold">
|
||||||
|
<%= gettext "Form" %>
|
||||||
|
</span>: <%= form.title %>
|
||||||
</span>
|
</span>
|
||||||
<%= if @state.position == index do %>
|
<%= if @state.position==index do %>
|
||||||
<%= if form.enabled do %>
|
<%= if form.enabled do %>
|
||||||
<button
|
<button
|
||||||
phx-click="form-set-inactive"
|
phx-click="form-set-inactive"
|
||||||
@@ -656,14 +673,14 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%= if @state.position == index do %>
|
<%= if @state.position==index do %>
|
||||||
<button class="underline" phx-click={toggle_add_modal()}>
|
<button class="underline" phx-click={toggle_add_modal()}>
|
||||||
<%= gettext("Add interaction") %>
|
<%= gettext("Add interaction") %>
|
||||||
</button>
|
</button>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<%= if @state.position == index && @state.position < @event.presentation_file.length - 1 do %>
|
<%= if @state.position==index && @state.position < @event.presentation_file.length - 1 do %>
|
||||||
<button
|
<button
|
||||||
phx-click="current-page"
|
phx-click="current-page"
|
||||||
phx-value-page={index + 1}
|
phx-value-page={index + 1}
|
||||||
@@ -685,13 +702,19 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="grid grid-cols-1 grid-rows-2 md:grid-rows-3">
|
<div class="grid grid-cols-1 grid-rows-2 md:grid-rows-3" style="height: 100%;">
|
||||||
<div class="bg-gray-200 md:row-span-2">
|
<div class="bg-gray-200 md:row-span-2 border-2">
|
||||||
<ul class="fixed z-20 flex items-center bg-gray-200 space-x-3 px-2 w-full py-2">
|
<ul class="fixed z-20 flex items-center bg-gray-200 space-x-3 px-2 w-full py-2">
|
||||||
<li class={"rounded-md #{if @list_tab == :posts, do: 'bg-secondary-600 text-white', else: 'bg-white text-gray-600' } px-2 py-0.5 text-sm shadow-sm"}>
|
<li class={"rounded-md #{if @list_tab==:posts, do: 'bg-secondary-600 text-white' ,
|
||||||
|
else: 'bg-white text-gray-600' } px-2 py-0.5 text-sm shadow-sm"}>
|
||||||
<%= link(gettext("Messages"), to: "#", phx_click: "list-tab", phx_value_tab: :posts) %>
|
<%= link(gettext("Messages"), to: "#", phx_click: "list-tab", phx_value_tab: :posts) %>
|
||||||
</li>
|
</li>
|
||||||
<li class={"rounded-md #{if @list_tab == :forms, do: 'bg-secondary-600 text-white', else: 'bg-white text-gray-600' } px-2 py-0.5 text-sm shadow-sm"}>
|
<li class={"rounded-md #{if @list_tab==:pinned_posts, do: 'bg-secondary-600 text-white' ,
|
||||||
|
else: 'bg-white text-gray-600' } px-2 py-0.5 text-sm shadow-sm"}>
|
||||||
|
<%= link(gettext("Pinned messages") <> " (#{ length(@pinned_posts)})", to: "#", phx_click: "list-tab", phx_value_tab: :pinned_posts) %>
|
||||||
|
</li>
|
||||||
|
<li class={"rounded-md #{if @list_tab==:forms, do: 'bg-secondary-600 text-white' ,
|
||||||
|
else: 'bg-white text-gray-600' } px-2 py-0.5 text-sm shadow-sm"}>
|
||||||
<%= link(gettext("Form submissions"),
|
<%= link(gettext("Form submissions"),
|
||||||
to: "#",
|
to: "#",
|
||||||
phx_click: "list-tab",
|
phx_click: "list-tab",
|
||||||
@@ -699,9 +722,13 @@
|
|||||||
) %>
|
) %>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<%= if @list_tab == :posts do %>
|
|
||||||
<%= if Enum.count(@posts) == 0 do %>
|
<%= if @list_tab==:posts do %>
|
||||||
<div class="text-center h-full flex flex-col space-y-5 items-center justify-center text-gray-400">
|
<%= if Enum.count(@all_posts)==0 && Enum.count(@pinned_posts)==0 do %>
|
||||||
|
<div
|
||||||
|
class="text-center flex flex-col space-y-5 items-center justify-center text-gray-400"
|
||||||
|
style="height: 100%;"
|
||||||
|
>
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
class="h-36 w-36"
|
class="h-36 w-36"
|
||||||
@@ -717,112 +744,346 @@
|
|||||||
/>
|
/>
|
||||||
</svg>
|
</svg>
|
||||||
|
|
||||||
<p class="text-lg"><%= gettext("Messages from attendees will appear here.") %></p>
|
<p class="text-lg">
|
||||||
|
<%= gettext("Messages from attendees will appear here.") %>
|
||||||
|
</p>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
<div
|
<div
|
||||||
id="post-list"
|
id="x"
|
||||||
class={"overflow-y-auto #{if Enum.count(@posts) > 0, do: 'max-h-full'} pb-5 pt-8 px-5"}
|
class={"overflow-y-auto #{if Enum.any?(@pinned_posts) or Enum.any?(@all_posts), do: 'h-full', else: 'h-1/2'}"}
|
||||||
phx-update="append"
|
|
||||||
data-posts-nb={Enum.count(@posts)}
|
|
||||||
phx-hook="ScrollIntoDiv"
|
|
||||||
data-target="#post-list"
|
|
||||||
>
|
>
|
||||||
<%= for post <- @posts do %>
|
|
||||||
<div class={if post.__meta__.state == :deleted, do: "hidden"} id={"#{post.id}-post"}>
|
<div
|
||||||
<div class="px-4 pb-2 pt-3 rounded-b-lg rounded-tr-lg bg-white relative shadow-md text-black break-all mt-4">
|
id="post-list"
|
||||||
<div class="float-right mr-1">
|
class={"overflow-y-auto #{if Enum.count(@all_posts)> 0, do: ''} pb-5 pt-8 px-5"}
|
||||||
<%= if post.attendee_identifier do %>
|
phx-update="append"
|
||||||
|
data-posts-nb={Enum.count(@all_posts)}
|
||||||
|
phx-hook="ScrollIntoDiv"
|
||||||
|
data-target="#post-list"
|
||||||
|
>
|
||||||
|
<%= for post <- @all_posts do %>
|
||||||
|
<div
|
||||||
|
class={if post.__meta__.state == :deleted, do: "hidden"}
|
||||||
|
id={"#{post.id}-post"}
|
||||||
|
>
|
||||||
|
<div class="px-4 pb-2 pt-3 rounded-b-lg rounded-tr-lg bg-white relative shadow-md text-black break-all mt-4">
|
||||||
|
<div class="float-right mr-1">
|
||||||
|
<%= if post.attendee_identifier do %>
|
||||||
|
<span class="text-yellow-500">
|
||||||
|
<%= link(
|
||||||
|
if post.pinned do
|
||||||
|
gettext("Unpin")
|
||||||
|
else
|
||||||
|
gettext("Pin")
|
||||||
|
end,
|
||||||
|
to: "#",
|
||||||
|
phx_click: "pin",
|
||||||
|
phx_value_id: post.uuid,
|
||||||
|
phx_value_event_id: @event.uuid
|
||||||
|
) %>
|
||||||
|
</span>
|
||||||
|
/
|
||||||
|
<span class="text-red-500">
|
||||||
|
<%= link(gettext("Ban"),
|
||||||
|
to: "#",
|
||||||
|
phx_click: "ban",
|
||||||
|
phx_value_attendee_identifier: post.attendee_identifier,
|
||||||
|
data: [
|
||||||
|
confirm:
|
||||||
|
gettext(
|
||||||
|
"Blocking this user will delete all his messages and he will not be able to join again, confirm ?"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
) %>
|
||||||
|
</span>
|
||||||
|
/
|
||||||
|
<% else %>
|
||||||
|
<span class="text-yellow-500">
|
||||||
|
<%= link(
|
||||||
|
if post.pinned do
|
||||||
|
gettext("Unpin")
|
||||||
|
else
|
||||||
|
gettext("Pin")
|
||||||
|
end,
|
||||||
|
to: "#",
|
||||||
|
phx_click: "pin",
|
||||||
|
phx_value_id: post.uuid,
|
||||||
|
phx_value_event_id: @event.uuid
|
||||||
|
) %>
|
||||||
|
</span>
|
||||||
|
/
|
||||||
|
<span class="text-red-500">
|
||||||
|
<%= link(gettext("Ban"),
|
||||||
|
to: "#",
|
||||||
|
phx_click: "ban",
|
||||||
|
phx_value_user_id: post.user_id,
|
||||||
|
data: [
|
||||||
|
confirm:
|
||||||
|
gettext(
|
||||||
|
"Blocking this user will delete all his messages and he will not be able to join again, confirm ?"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
) %>
|
||||||
|
</span>
|
||||||
|
/
|
||||||
|
<% end %>
|
||||||
<span class="text-red-500">
|
<span class="text-red-500">
|
||||||
<%= link(gettext("Ban"),
|
<%= link(gettext("Delete"),
|
||||||
to: "#",
|
to: "#",
|
||||||
phx_click: "ban",
|
phx_click: "delete",
|
||||||
phx_value_attendee_identifier: post.attendee_identifier,
|
phx_value_id: post.uuid,
|
||||||
data: [
|
phx_value_event_id: @event.uuid
|
||||||
confirm:
|
|
||||||
gettext(
|
|
||||||
"Blocking this user will delete all his messages and he will not be able to join again, confirm ?"
|
|
||||||
)
|
|
||||||
]
|
|
||||||
) %>
|
) %>
|
||||||
</span>
|
</span>
|
||||||
/
|
</div>
|
||||||
<% else %>
|
|
||||||
<span class="text-red-500">
|
|
||||||
<%= link(gettext("Ban"),
|
|
||||||
to: "#",
|
|
||||||
phx_click: "ban",
|
|
||||||
phx_value_user_id: post.user_id,
|
|
||||||
data: [
|
|
||||||
confirm:
|
|
||||||
gettext(
|
|
||||||
"Blocking this user will delete all his messages and he will not be able to join again, confirm ?"
|
|
||||||
)
|
|
||||||
]
|
|
||||||
) %>
|
|
||||||
</span>
|
|
||||||
/
|
|
||||||
<% end %>
|
|
||||||
<span class="text-red-500">
|
|
||||||
<%= link(gettext("Delete"),
|
|
||||||
to: "#",
|
|
||||||
phx_click: "delete",
|
|
||||||
phx_value_id: post.uuid,
|
|
||||||
phx_value_event_id: @event.uuid
|
|
||||||
) %>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div class="flex space-x-3 items-center">
|
<div class="flex space-x-3 items-center">
|
||||||
<%= if post.attendee_identifier do %>
|
<%= if post.attendee_identifier do %>
|
||||||
<img
|
<img
|
||||||
class="h-8 w-8"
|
class="h-8 w-8"
|
||||||
src={"https://avatars.dicebear.com/api/identicon/#{post.attendee_identifier}.svg"}
|
src={"https://avatars.dicebear.com/api/identicon/#{post.attendee_identifier}.svg"}
|
||||||
/>
|
/>
|
||||||
<% else %>
|
<% else %>
|
||||||
<img
|
<img
|
||||||
class="h-8 w-8"
|
class="h-8 w-8"
|
||||||
src={"https://avatars.dicebear.com/api/identicon/#{post.user_id}.svg"}
|
src={"https://avatars.dicebear.com/api/identicon/#{post.user_id}.svg"}
|
||||||
/>
|
/>
|
||||||
<% end %>
|
|
||||||
|
|
||||||
<div class="flex flex-col">
|
|
||||||
<%= if post.name do %>
|
|
||||||
<p class="text-black text-sm font-semibold mr-2"><%= post.name %></p>
|
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
<p class="text-xl"><%= post.body %></p>
|
<div class="flex flex-col">
|
||||||
|
<%= if post.name do %>
|
||||||
|
<p class="text-black text-sm font-semibold mr-2">
|
||||||
|
<%= post.name %>
|
||||||
|
</p>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<p class="text-xl">
|
||||||
|
<%= post.body %>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%= if post.like_count> 0 || post.love_count > 0 || post.lol_count > 0 do %>
|
||||||
|
<div class="flex h-6 space-x-2 text-base text-gray-500 pb-3 items-center mt-5">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<%= if post.like_count> 0 do %>
|
||||||
|
<img src="/images/icons/thumb.svg" class="h-4" />
|
||||||
|
<span class="ml-1">
|
||||||
|
<%= post.like_count %>
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<%= if post.love_count> 0 do %>
|
||||||
|
<img src="/images/icons/heart.svg" class="h-4" />
|
||||||
|
<span class="ml-1">
|
||||||
|
<%= post.love_count %>
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<%= if post.lol_count> 0 do %>
|
||||||
|
<img src="/images/icons/laugh.svg" class="h-4" />
|
||||||
|
<span class="ml-1">
|
||||||
|
<%= post.lol_count %>
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<!-- The div below encompasses the 2 post lists -->
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
<%= if @list_tab==:pinned_posts do %>
|
||||||
|
<%= if Enum.count(@pinned_posts)==0 do %>
|
||||||
|
<div
|
||||||
|
class="text-center flex flex-col space-y-5 items-center justify-center text-gray-400"
|
||||||
|
style="height: 100%;"
|
||||||
|
>
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="h-36 w-36"
|
||||||
|
fill="none"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke="currentColor"
|
||||||
|
stroke-width="2"
|
||||||
|
>
|
||||||
|
<path
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
d="M17 8h2a2 2 0 012 2v6a2 2 0 01-2 2h-2v4l-4-4H9a1.994 1.994 0 01-1.414-.586m0 0L11 14h4a2 2 0 002-2V6a2 2 0 00-2-2H5a2 2 0 00-2 2v6a2 2 0 002 2h2v4l.586-.586z"
|
||||||
|
/>
|
||||||
|
</svg>
|
||||||
|
|
||||||
|
<p class="text-lg">
|
||||||
|
<%= gettext("Pinned messages will appear here.") %>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
<div
|
||||||
|
id="x"
|
||||||
|
class={"overflow-y-auto #{if Enum.any?(@pinned_posts) or Enum.any?(@all_posts), do: 'h-full', else: 'h-1/2'}"}
|
||||||
|
>
|
||||||
|
<%= if Enum.any?(@pinned_posts) do %>
|
||||||
|
<div
|
||||||
|
id="pinned-post-list"
|
||||||
|
class={"overflow-y-auto #{if Enum.count(@pinned_posts)> 0, do: ''}
|
||||||
|
pt-8 px-5"}
|
||||||
|
phx-update="replace"
|
||||||
|
data-posts-nb={Enum.count(@pinned_posts)}
|
||||||
|
phx-hook="ScrollIntoDiv"
|
||||||
|
data-target="#pinned-post-list"
|
||||||
|
>
|
||||||
|
<%= for post <- @pinned_posts do %>
|
||||||
|
<div
|
||||||
|
class={if post.__meta__.state == :deleted, do: "hidden"}
|
||||||
|
id={"#{post.id}-post"}
|
||||||
|
>
|
||||||
|
<div class="px-4 pb-2 pt-3 rounded-b-lg rounded-tr-lg bg-white relative shadow-md text-black break-all mt-4">
|
||||||
|
<div class="float-right mr-1">
|
||||||
|
<%= if post.attendee_identifier do %>
|
||||||
|
<span class="text-yellow-500">
|
||||||
|
<%= link(
|
||||||
|
if post.pinned do
|
||||||
|
gettext("Unpin")
|
||||||
|
else
|
||||||
|
gettext("Pin")
|
||||||
|
end,
|
||||||
|
to: "#",
|
||||||
|
phx_click: "pin",
|
||||||
|
phx_value_id: post.uuid,
|
||||||
|
phx_value_event_id: @event.uuid
|
||||||
|
) %>
|
||||||
|
</span>
|
||||||
|
/
|
||||||
|
<span class="text-red-500">
|
||||||
|
<%= link(gettext("Ban"),
|
||||||
|
to: "#",
|
||||||
|
phx_click: "ban",
|
||||||
|
phx_value_attendee_identifier: post.attendee_identifier,
|
||||||
|
data: [
|
||||||
|
confirm:
|
||||||
|
gettext(
|
||||||
|
"Blocking this user will delete all his messages and he will not be able to join again, confirm ?"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
) %>
|
||||||
|
</span>
|
||||||
|
/
|
||||||
|
<% else %>
|
||||||
|
<span class="text-yellow-500">
|
||||||
|
<%= link(
|
||||||
|
if post.pinned do
|
||||||
|
gettext("Unpin")
|
||||||
|
else
|
||||||
|
gettext("Pin")
|
||||||
|
end,
|
||||||
|
to: "#",
|
||||||
|
phx_click: "pin",
|
||||||
|
phx_value_id: post.uuid,
|
||||||
|
phx_value_event_id: @event.uuid
|
||||||
|
) %>
|
||||||
|
</span>
|
||||||
|
/
|
||||||
|
<span class="text-red-500">
|
||||||
|
<%= link(gettext("Ban"),
|
||||||
|
to: "#",
|
||||||
|
phx_click: "ban",
|
||||||
|
phx_value_user_id: post.user_id,
|
||||||
|
data: [
|
||||||
|
confirm:
|
||||||
|
gettext(
|
||||||
|
"Blocking this user will delete all his messages and he will not be able to join again, confirm ?"
|
||||||
|
)
|
||||||
|
]
|
||||||
|
) %>
|
||||||
|
</span>
|
||||||
|
/
|
||||||
|
<% end %>
|
||||||
|
<span class="text-red-500">
|
||||||
|
<%= link(gettext("Delete"),
|
||||||
|
to: "#",
|
||||||
|
phx_click: "delete",
|
||||||
|
phx_value_id: post.uuid,
|
||||||
|
phx_value_event_id: @event.uuid
|
||||||
|
) %>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class="flex space-x-3 items-center">
|
||||||
|
<%= if post.attendee_identifier do %>
|
||||||
|
<img
|
||||||
|
class="h-8 w-8"
|
||||||
|
src={"https://avatars.dicebear.com/api/identicon/#{post.attendee_identifier}.svg"}
|
||||||
|
/>
|
||||||
|
<% else %>
|
||||||
|
<img
|
||||||
|
class="h-8 w-8"
|
||||||
|
src={"https://avatars.dicebear.com/api/identicon/#{post.user_id}.svg"}
|
||||||
|
/>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<div class="flex flex-col">
|
||||||
|
<%= if post.name do %>
|
||||||
|
<p class="text-black text-sm font-semibold mr-2">
|
||||||
|
<%= post.name %>
|
||||||
|
</p>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
|
<p class="text-xl">
|
||||||
|
<%= post.body %>
|
||||||
|
</p>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<%= if post.like_count> 0 || post.love_count > 0 || post.lol_count > 0 do %>
|
||||||
|
<div class="flex h-6 space-x-2 text-base text-gray-500 pb-3 items-center mt-5">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<%= if post.like_count> 0 do %>
|
||||||
|
<img src="/images/icons/thumb.svg" class="h-4" />
|
||||||
|
<span class="ml-1">
|
||||||
|
<%= post.like_count %>
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<%= if post.love_count> 0 do %>
|
||||||
|
<img src="/images/icons/heart.svg" class="h-4" />
|
||||||
|
<span class="ml-1">
|
||||||
|
<%= post.love_count %>
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<%= if post.lol_count> 0 do %>
|
||||||
|
<img src="/images/icons/laugh.svg" class="h-4" />
|
||||||
|
<span class="ml-1">
|
||||||
|
<%= post.lol_count %>
|
||||||
|
</span>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<% end %>
|
||||||
<%= if post.like_count > 0 || post.love_count > 0 || post.lol_count > 0 do %>
|
|
||||||
<div class="flex h-6 space-x-2 text-base text-gray-500 pb-3 items-center mt-5">
|
|
||||||
<div class="flex items-center">
|
|
||||||
<%= if post.like_count > 0 do %>
|
|
||||||
<img src="/images/icons/thumb.svg" class="h-4" />
|
|
||||||
<span class="ml-1"><%= post.like_count %></span>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<%= if post.love_count > 0 do %>
|
|
||||||
<img src="/images/icons/heart.svg" class="h-4" />
|
|
||||||
<span class="ml-1"><%= post.love_count %></span>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
<div class="flex items-center">
|
|
||||||
<%= if post.lol_count > 0 do %>
|
|
||||||
<img src="/images/icons/laugh.svg" class="h-4" />
|
|
||||||
<span class="ml-1"><%= post.lol_count %></span>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<% end %>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
<% else %>
|
<% end %>
|
||||||
<%= if Enum.count(@form_submits) == 0 do %>
|
|
||||||
|
|
||||||
|
<%= if @list_tab==:forms do %>
|
||||||
|
<%= if Enum.count(@form_submits)==0 do %>
|
||||||
<div class="text-center h-full flex flex-col space-y-5 items-center justify-center text-gray-400">
|
<div class="text-center h-full flex flex-col space-y-5 items-center justify-center text-gray-400">
|
||||||
<svg
|
<svg
|
||||||
xmlns="http://www.w3.org/2000/svg"
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
@@ -850,7 +1111,8 @@
|
|||||||
<% end %>
|
<% end %>
|
||||||
<div
|
<div
|
||||||
id="form-list"
|
id="form-list"
|
||||||
class={"overflow-y-auto #{if Enum.count(@form_submits) > 0, do: 'max-h-full'} pb-5 pt-8 px-5"}
|
class={"overflow-y-auto #{if Enum.count(@form_submits)> 0, do: 'max-h-full'}
|
||||||
|
pb-5 pt-8 px-5"}
|
||||||
phx-update="append"
|
phx-update="append"
|
||||||
data-forms-nb={Enum.count(@form_submits)}
|
data-forms-nb={Enum.count(@form_submits)}
|
||||||
phx-hook="ScrollIntoDiv"
|
phx-hook="ScrollIntoDiv"
|
||||||
@@ -889,7 +1151,12 @@
|
|||||||
|
|
||||||
<div>
|
<div>
|
||||||
<%= for res <- submission.response do %>
|
<%= for res <- submission.response do %>
|
||||||
<p><strong><%= elem(res, 0) %>:</strong> <%= elem(res, 1) %></p>
|
<p>
|
||||||
|
<strong>
|
||||||
|
<%= elem(res, 0) %>:
|
||||||
|
</strong>
|
||||||
|
<%= elem(res, 1) %>
|
||||||
|
</p>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
@@ -903,7 +1170,9 @@
|
|||||||
<div class="w-full shadow-lg">
|
<div class="w-full shadow-lg">
|
||||||
<div class="px-5 py-3 grid grid-cols-1 sm:grid-cols-2">
|
<div class="px-5 py-3 grid grid-cols-1 sm:grid-cols-2">
|
||||||
<div>
|
<div>
|
||||||
<span class="font-semibold text-lg"><%= gettext("On screen settings") %></span>
|
<span class="font-semibold text-lg">
|
||||||
|
<%= gettext("On screen settings") %>
|
||||||
|
</span>
|
||||||
|
|
||||||
<div class="flex space-x-2 items-center mt-3">
|
<div class="flex space-x-2 items-center mt-3">
|
||||||
<ClaperWeb.Component.Input.check
|
<ClaperWeb.Component.Input.check
|
||||||
@@ -923,7 +1192,17 @@
|
|||||||
<span><%= gettext("Show messages") %><code class="pl-1">(W)</code></span>
|
<span><%= gettext("Show messages") %><code class="pl-1">(W)</code></span>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class={"#{if !@current_poll, do: 'opacity-50'} flex space-x-2 items-center mt-3"}>
|
<div class="flex space-x-2 items-center mt-3">
|
||||||
|
<ClaperWeb.Component.Input.check
|
||||||
|
key={:show_only_pinned}
|
||||||
|
checked={@state.show_only_pinned}
|
||||||
|
/>
|
||||||
|
<span>
|
||||||
|
<%= gettext("Show only pinned messages") %>
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div class={"#{if !@current_poll, do: 'opacity-50' } flex space-x-2 items-center mt-3"}>
|
||||||
<ClaperWeb.Component.Input.check
|
<ClaperWeb.Component.Input.check
|
||||||
key={:poll_visible}
|
key={:poll_visible}
|
||||||
disabled={!@current_poll}
|
disabled={!@current_poll}
|
||||||
@@ -935,7 +1214,9 @@
|
|||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div>
|
<div>
|
||||||
<span class="font-semibold text-lg"><%= gettext("Attendees settings") %></span>
|
<span class="font-semibold text-lg">
|
||||||
|
<%= gettext("Attendees settings") %>
|
||||||
|
</span>
|
||||||
|
|
||||||
<div class="flex space-x-2 items-center mt-3">
|
<div class="flex space-x-2 items-center mt-3">
|
||||||
<ClaperWeb.Component.Input.check
|
<ClaperWeb.Component.Input.check
|
||||||
|
|||||||
@@ -33,6 +33,32 @@ defmodule ClaperWeb.EventLive.PostComponent do
|
|||||||
<span><%= gettext("Host") %></span>
|
<span><%= gettext("Host") %></span>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
<%= if is_pinned(@post) do %>
|
||||||
|
<div class="inline-flex items-center space-x-1 justify-center px-3 py-0.5 rounded-full text-xs font-medium bg-supporting-yellow-100 text-supporting-yellow-800 mb-2 ml-1">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="icon icon-tabler icon-tabler-pin-filled"
|
||||||
|
width="12"
|
||||||
|
height="12"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke="currentColor"
|
||||||
|
fill="none"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||||
|
<path
|
||||||
|
d="M15.113 3.21l.094 .083l5.5 5.5a1 1 0 0 1 -1.175 1.59l-3.172 3.171l-1.424 3.797a1 1 0 0 1 -.158 .277l-.07 .08l-1.5 1.5a1 1 0 0 1 -1.32 .082l-.095 -.083l-2.793 -2.792l-3.793 3.792a1 1 0 0 1 -1.497 -1.32l.083 -.094l3.792 -3.793l-2.792 -2.793a1 1 0 0 1 -.083 -1.32l.083 -.094l1.5 -1.5a1 1 0 0 1 .258 -.187l.098 -.042l3.796 -1.425l3.171 -3.17a1 1 0 0 1 1.497 -1.26z"
|
||||||
|
stroke-width="0"
|
||||||
|
fill="currentColor"
|
||||||
|
>
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
<span><%= gettext("Pinned") %></span>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
@@ -124,6 +150,32 @@ defmodule ClaperWeb.EventLive.PostComponent do
|
|||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
|
|
||||||
|
<%= if is_pinned(@post) do %>
|
||||||
|
<div class="inline-flex items-center space-x-1 justify-center px-3 py-0.5 rounded-full text-xs font-medium bg-supporting-yellow-100 text-supporting-yellow-800 mb-2 ml-1">
|
||||||
|
<svg
|
||||||
|
xmlns="http://www.w3.org/2000/svg"
|
||||||
|
class="icon icon-tabler icon-tabler-pin-filled"
|
||||||
|
width="12"
|
||||||
|
height="12"
|
||||||
|
viewBox="0 0 24 24"
|
||||||
|
stroke-width="2"
|
||||||
|
stroke="currentColor"
|
||||||
|
fill="none"
|
||||||
|
stroke-linecap="round"
|
||||||
|
stroke-linejoin="round"
|
||||||
|
>
|
||||||
|
<path stroke="none" d="M0 0h24v24H0z" fill="none"></path>
|
||||||
|
<path
|
||||||
|
d="M15.113 3.21l.094 .083l5.5 5.5a1 1 0 0 1 -1.175 1.59l-3.172 3.171l-1.424 3.797a1 1 0 0 1 -.158 .277l-.07 .08l-1.5 1.5a1 1 0 0 1 -1.32 .082l-.095 -.083l-2.793 -2.792l-3.793 3.792a1 1 0 0 1 -1.497 -1.32l.083 -.094l3.792 -3.793l-2.792 -2.793a1 1 0 0 1 -.083 -1.32l.083 -.094l1.5 -1.5a1 1 0 0 1 .258 -.187l.098 -.042l3.796 -1.425l3.171 -3.17a1 1 0 0 1 1.497 -1.26z"
|
||||||
|
stroke-width="0"
|
||||||
|
fill="currentColor"
|
||||||
|
>
|
||||||
|
</path>
|
||||||
|
</svg>
|
||||||
|
<span><%= gettext("Pinned") %></span>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
|
||||||
<p><%= @post.body %></p>
|
<p><%= @post.body %></p>
|
||||||
|
|
||||||
<div class="flex h-6 text-xs float-right space-x-2">
|
<div class="flex h-6 text-xs float-right space-x-2">
|
||||||
@@ -218,4 +270,8 @@ defmodule ClaperWeb.EventLive.PostComponent do
|
|||||||
leader.user_id == post.user_id
|
leader.user_id == post.user_id
|
||||||
end))
|
end))
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp is_pinned(post) do
|
||||||
|
post.pinned == true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -46,15 +46,23 @@ defmodule ClaperWeb.EventLive.Presenter do
|
|||||||
|> assign(:event, event)
|
|> assign(:event, event)
|
||||||
|> assign(:state, event.presentation_file.presentation_state)
|
|> assign(:state, event.presentation_file.presentation_state)
|
||||||
|> assign(:posts, list_posts(socket, event.uuid))
|
|> assign(:posts, list_posts(socket, event.uuid))
|
||||||
|
|> assign(:pinned_posts, list_pinned_posts(socket, event.uuid))
|
||||||
|
|> assign(:show_only_pinned, event.presentation_file.presentation_state.show_only_pinned)
|
||||||
|> assign(:reacts, [])
|
|> assign(:reacts, [])
|
||||||
|> poll_at_position
|
|> poll_at_position
|
||||||
|> form_at_position
|
|> form_at_position
|
||||||
|> embed_at_position
|
|> embed_at_position
|
||||||
|
|
||||||
{:ok, socket, temporary_assigns: [posts: []]}
|
{:ok, socket, temporary_assigns: []}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp update_post_in_list(posts, updated_post) do
|
||||||
|
Enum.map(posts, fn post ->
|
||||||
|
if post.id == updated_post.id, do: updated_post, else: post
|
||||||
|
end)
|
||||||
|
end
|
||||||
|
|
||||||
defp is_leader(%{assigns: %{current_user: current_user}} = _socket, event) do
|
defp is_leader(%{assigns: %{current_user: current_user}} = _socket, event) do
|
||||||
Claper.Events.is_leaded_by(current_user.email, event) || event.user.id == current_user.id
|
Claper.Events.is_leaded_by(current_user.email, event) || event.user.id == current_user.id
|
||||||
end
|
end
|
||||||
@@ -74,6 +82,22 @@ defmodule ClaperWeb.EventLive.Presenter do
|
|||||||
|> update(:posts, fn posts -> [post | posts] end)}
|
|> update(:posts, fn posts -> [post | posts] end)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_info({:post_pinned, post}, socket) do
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> update(:pinned_posts, fn pinned_posts -> [post | pinned_posts] end)}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_info({:post_unpinned, post}, socket) do
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> update(:pinned_posts, fn pinned_posts ->
|
||||||
|
Enum.reject(pinned_posts, fn p -> p.id == post.id end)
|
||||||
|
end)}
|
||||||
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_info({:state_updated, state}, socket) do
|
def handle_info({:state_updated, state}, socket) do
|
||||||
{:noreply,
|
{:noreply,
|
||||||
@@ -86,23 +110,23 @@ defmodule ClaperWeb.EventLive.Presenter do
|
|||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_info({:post_updated, post}, socket) do
|
def handle_info({:post_updated, updated_post}, socket) do
|
||||||
{:noreply, socket |> update(:posts, fn posts -> [post | posts] end)}
|
updated_posts = update_post_in_list(socket.assigns.posts, updated_post)
|
||||||
end
|
updated_pinned_posts = update_post_in_list(socket.assigns.pinned_posts, updated_post)
|
||||||
|
|
||||||
@impl true
|
{:noreply,
|
||||||
def handle_info({:reaction_added, post}, socket) do
|
socket
|
||||||
{:noreply, socket |> update(:posts, fn posts -> [post | posts] end)}
|
|> assign(:posts, updated_posts)
|
||||||
end
|
|> assign(:pinned_posts, updated_pinned_posts)}
|
||||||
|
|
||||||
@impl true
|
|
||||||
def handle_info({:reaction_removed, post}, socket) do
|
|
||||||
{:noreply, socket |> update(:posts, fn posts -> [post | posts] end)}
|
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_info({:post_deleted, post}, socket) do
|
def handle_info({:post_deleted, post}, socket) do
|
||||||
{:noreply, socket |> update(:posts, fn posts -> [post | posts] end)}
|
updated_posts = Enum.reject(socket.assigns.posts, fn p -> p.id == post.id end)
|
||||||
|
updated_pinned_posts = Enum.reject(socket.assigns.pinned_posts, fn p -> p.id == post.id end)
|
||||||
|
|
||||||
|
{:noreply,
|
||||||
|
socket |> assign(:posts, updated_posts) |> assign(:pinned_posts, updated_pinned_posts)}
|
||||||
end
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
@@ -173,6 +197,14 @@ defmodule ClaperWeb.EventLive.Presenter do
|
|||||||
|> update(:chat_visible, fn _chat_visible -> value end)}
|
|> update(:chat_visible, fn _chat_visible -> value end)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_info({:show_only_pinned, value}, socket) do
|
||||||
|
{:noreply,
|
||||||
|
socket
|
||||||
|
|> push_event("show_only_pinned", %{value: value})
|
||||||
|
|> update(:show_only_pinned, fn _show_only_pinned -> value end)}
|
||||||
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_info({:poll_visible, value}, socket) do
|
def handle_info({:poll_visible, value}, socket) do
|
||||||
{:noreply,
|
{:noreply,
|
||||||
@@ -267,4 +299,8 @@ defmodule ClaperWeb.EventLive.Presenter do
|
|||||||
defp list_posts(_socket, event_id) do
|
defp list_posts(_socket, event_id) do
|
||||||
Claper.Posts.list_posts(event_id, [:event, :reactions])
|
Claper.Posts.list_posts(event_id, [:event, :reactions])
|
||||||
end
|
end
|
||||||
|
|
||||||
|
defp list_pinned_posts(_socket, event_id) do
|
||||||
|
Claper.Posts.list_pinned_posts(event_id, [:event, :reactions])
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|||||||
@@ -89,40 +89,80 @@
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
class={"#{if @state.chat_visible, do: 'opacity-100 w-3/12 px-4 showed', else: 'opacity-0 w-0 p-0'} transition-all duration-150 flex flex-col h-screen py-5 justify-end max-h-screen bg-black"}
|
class={"#{if @state.chat_visible, do: 'opacity-100 w-3/12 px-4 showed', else: 'opacity-0 w-0 p-0'} transition-all duration-150 flex flex-col h-screen py-5 justify-end max-h-screen bg-black"}
|
||||||
id="post-list"
|
id="test"
|
||||||
phx-update="append"
|
phx-update="replace"
|
||||||
>
|
>
|
||||||
<%= for post <- @posts do %>
|
<%= if @state.show_only_pinned == false do %>
|
||||||
<div class={if post.__meta__.state == :deleted, do: "hidden"} id={"#{post.id}-post"}>
|
<div id="post-list" phx-update="replace">
|
||||||
<div class="px-4 pb-2 pt-3 rounded-b-lg rounded-tr-lg bg-white shadow-md text-black break-word mt-4">
|
<%= for post <- @posts do %>
|
||||||
<%= if post.name do %>
|
<div class={if post.__meta__.state == :deleted, do: "hidden"} id={"#{post.id}-post"}>
|
||||||
<p class="text-gray-400 text-lg font-semibold mb-2 mr-2"><%= post.name %></p>
|
<div class="px-4 pb-2 pt-3 rounded-b-lg rounded-tr-lg bg-white shadow-md text-black break-word mt-4">
|
||||||
<% end %>
|
<%= if post.name do %>
|
||||||
<p class="text-3xl"><%= post.body %></p>
|
<p class="text-gray-400 text-lg font-semibold mb-2 mr-2"><%= post.name %></p>
|
||||||
|
<% end %>
|
||||||
|
<p class="text-3xl"><%= post.body %></p>
|
||||||
|
|
||||||
<%= if post.like_count > 0 || post.love_count > 0 || post.lol_count > 0 do %>
|
<%= if post.like_count > 0 || post.love_count > 0 || post.lol_count > 0 do %>
|
||||||
<div class="flex h-6 space-x-2 text-lg text-gray-500 pb-3 items-center mt-5">
|
<div class="flex h-6 space-x-2 text-lg text-gray-500 pb-3 items-center mt-5">
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<%= if post.like_count > 0 do %>
|
<%= if post.like_count > 0 do %>
|
||||||
<img src="/images/icons/thumb.svg" class="h-7" />
|
<img src="/images/icons/thumb.svg" class="h-7" />
|
||||||
<span class="ml-1"><%= post.like_count %></span>
|
<span class="ml-1"><%= post.like_count %></span>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<%= if post.love_count > 0 do %>
|
<%= if post.love_count > 0 do %>
|
||||||
<img src="/images/icons/heart.svg" class="h-7" />
|
<img src="/images/icons/heart.svg" class="h-7" />
|
||||||
<span class="ml-1"><%= post.love_count %></span>
|
<span class="ml-1"><%= post.love_count %></span>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
<div class="flex items-center">
|
<div class="flex items-center">
|
||||||
<%= if post.lol_count > 0 do %>
|
<%= if post.lol_count > 0 do %>
|
||||||
<img src="/images/icons/laugh.svg" class="h-7" />
|
<img src="/images/icons/laugh.svg" class="h-7" />
|
||||||
<span class="ml-1"><%= post.lol_count %></span>
|
<span class="ml-1"><%= post.lol_count %></span>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
</div>
|
||||||
</div>
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<% else %>
|
||||||
|
<div id="pinned-posts" phx-update="replace">
|
||||||
|
<%= for post <- @pinned_posts do %>
|
||||||
|
<div class={if post.__meta__.state == :deleted, do: "hidden"} id={"#{post.id}-post"}>
|
||||||
|
<div class="px-4 pb-2 pt-3 rounded-b-lg rounded-tr-lg bg-white shadow-md text-black break-word mt-4">
|
||||||
|
<%= if post.name do %>
|
||||||
|
<p class="text-gray-400 text-lg font-semibold mb-2 mr-2"><%= post.name %></p>
|
||||||
|
<% end %>
|
||||||
|
<p class="text-3xl"><%= post.body %></p>
|
||||||
|
|
||||||
|
<%= if post.like_count > 0 || post.love_count > 0 || post.lol_count > 0 do %>
|
||||||
|
<div class="flex h-6 space-x-2 text-lg text-gray-500 pb-3 items-center mt-5">
|
||||||
|
<div class="flex items-center">
|
||||||
|
<%= if post.like_count > 0 do %>
|
||||||
|
<img src="/images/icons/thumb.svg" class="h-7" />
|
||||||
|
<span class="ml-1"><%= post.like_count %></span>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<%= if post.love_count > 0 do %>
|
||||||
|
<img src="/images/icons/heart.svg" class="h-7" />
|
||||||
|
<span class="ml-1"><%= post.love_count %></span>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
<div class="flex items-center">
|
||||||
|
<%= if post.lol_count > 0 do %>
|
||||||
|
<img src="/images/icons/laugh.svg" class="h-7" />
|
||||||
|
<span class="ml-1"><%= post.lol_count %></span>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
<% end %>
|
<% end %>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
@@ -259,6 +259,16 @@ defmodule ClaperWeb.EventLive.Show do
|
|||||||
{:noreply, socket |> update(:posts, fn posts -> [post | posts] end)}
|
{:noreply, socket |> update(:posts, fn posts -> [post | posts] end)}
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_info({:post_pinned, post}, socket) do
|
||||||
|
{:noreply, socket |> update(:posts, fn posts -> [post | posts] end)}
|
||||||
|
end
|
||||||
|
|
||||||
|
@impl true
|
||||||
|
def handle_info({:post_unpinned, post}, socket) do
|
||||||
|
{:noreply, socket |> update(:posts, fn posts -> [post | posts] end)}
|
||||||
|
end
|
||||||
|
|
||||||
@impl true
|
@impl true
|
||||||
def handle_info({:reaction_added, post}, socket) do
|
def handle_info({:reaction_added, post}, socket) do
|
||||||
{:noreply, socket |> update(:posts, fn posts -> [post | posts] end)}
|
{:noreply, socket |> update(:posts, fn posts -> [post | posts] end)}
|
||||||
|
|||||||
@@ -0,0 +1,13 @@
|
|||||||
|
defmodule Claper.Repo.Migrations.AddPinnedToPostsAndPresentationStates do
|
||||||
|
use Ecto.Migration
|
||||||
|
|
||||||
|
def change do
|
||||||
|
alter table(:presentation_states) do
|
||||||
|
add :show_only_pinned, :boolean, default: false
|
||||||
|
end
|
||||||
|
|
||||||
|
alter table(:posts) do
|
||||||
|
add :pinned, :boolean, default: false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
Reference in New Issue
Block a user