diff --git a/lib/who_need_help/help.ex b/lib/who_need_help/help.ex index cff2fd0..7a89b8c 100644 --- a/lib/who_need_help/help.ex +++ b/lib/who_need_help/help.ex @@ -352,7 +352,7 @@ defmodule WhoNeedHelp.Help do is_nil(request) -> {:error, :not_found} - request.requester_id == user.id and request.status in [:open, :matched] -> + request.requester_id == user.id and request.status in [:open, :matched, :in_progress] -> now = DateTime.utc_now(:second) assignment = diff --git a/lib/who_need_help/messaging.ex b/lib/who_need_help/messaging.ex index 7407325..2e4796d 100644 --- a/lib/who_need_help/messaging.ex +++ b/lib/who_need_help/messaging.ex @@ -60,25 +60,32 @@ defmodule WhoNeedHelp.Messaging do request = current.request recipient_id = counterpart_id(user.id, current, request) - with true <- Help.participant?(scope, current), - :ok <- Trust.lock_user_pair(user.id, recipient_id), - false <- Trust.blocked_between?(user.id, recipient_id), - {:ok, message} <- - %Message{assignment_id: current.id, sender_id: user.id} - |> Message.changeset(attrs) - |> Repo.insert(), - {:ok, _push_job} <- - Push.enqueue_message_created( - message.id, - current.id, - request.id, - recipient_id - ) do - {:ok, message} - else - true -> {:error, :blocked} - false -> {:error, :forbidden} - other -> other + cond do + not Help.participant?(scope, current) -> + {:error, :forbidden} + + current.status not in [:accepted, :in_progress] -> + {:error, :assignment_inactive} + + true -> + with :ok <- Trust.lock_user_pair(user.id, recipient_id), + false <- Trust.blocked_between?(user.id, recipient_id), + {:ok, message} <- + %Message{assignment_id: current.id, sender_id: user.id} + |> Message.changeset(attrs) + |> Repo.insert(), + {:ok, _push_job} <- + Push.enqueue_message_created( + message.id, + current.id, + request.id, + recipient_id + ) do + {:ok, message} + else + true -> {:error, :blocked} + other -> other + end end else {:error, :not_found} diff --git a/lib/who_need_help_web/live/request_live/show.ex b/lib/who_need_help_web/live/request_live/show.ex index cd0904b..57b24d1 100644 --- a/lib/who_need_help_web/live/request_live/show.ex +++ b/lib/who_need_help_web/live/request_live/show.ex @@ -65,7 +65,13 @@ defmodule WhoNeedHelpWeb.RequestLive.Show do def handle_info({event, request}, socket) when event in [:request_updated, :request_created] do case Help.get_request(socket.assigns.current_scope, request.id) do {:ok, request} -> - socket = maybe_subscribe_assignment(socket, request) + previous_status = socket.assigns.request.status + + socket = + socket + |> maybe_subscribe_assignment(request) + |> maybe_put_status_transition_flash(previous_status, request.status) + {:noreply, sync_tracking_after_request_update(socket, request)} {:error, :not_found} -> @@ -369,11 +375,14 @@ defmodule WhoNeedHelpWeb.RequestLive.Show do socket.assigns.other_user_id ) - {:noreply, - socket - |> assign(:blocked_by_current, false) - |> assign(:interaction_blocked, interaction_blocked) - |> put_flash(:info, gettext("User unblocked."))} + socket = + socket + |> assign(:blocked_by_current, false) + |> assign(:interaction_blocked, interaction_blocked) + |> restore_private_interaction(interaction_blocked) + |> put_flash(:info, gettext("User unblocked.")) + + {:noreply, socket} {:error, reason} -> {:noreply, put_flash(socket, :error, message(reason))} @@ -436,6 +445,55 @@ defmodule WhoNeedHelpWeb.RequestLive.Show do end end + defp maybe_put_status_transition_flash(socket, status, status), do: socket + + defp maybe_put_status_transition_flash(socket, _previous, :matched) do + put_flash( + socket, + :info, + gettext("A volunteer accepted this request. Use private chat to coordinate safely.") + ) + end + + defp maybe_put_status_transition_flash(socket, _previous, :in_progress) do + put_flash(socket, :info, gettext("Help is now in progress.")) + end + + defp maybe_put_status_transition_flash(socket, _previous, :completed) do + put_flash(socket, :info, gettext("Help is complete.")) + end + + defp maybe_put_status_transition_flash(socket, _previous, :cancelled) do + put_flash(socket, :info, gettext("This request was cancelled.")) + end + + defp maybe_put_status_transition_flash(socket, _previous, _status), do: socket + + defp restore_private_interaction(socket, true), do: socket + + defp restore_private_interaction(%{assigns: %{assignment: nil}} = socket, false), do: socket + + defp restore_private_interaction(socket, false) do + assignment = socket.assigns.assignment + + messages_page = + Messaging.paginate_messages(socket.assigns.current_scope, assignment) + + positions = + if assignment.status in [:accepted, :in_progress], + do: Tracking.list_current_positions(socket.assigns.current_scope, assignment), + else: %{} + + socket + |> assign(:messages, messages_page.entries) + |> assign(:messages_cursor, messages_page.next_cursor) + |> assign( + :message_window_limit, + max(length(messages_page.entries), @initial_message_window) + ) + |> assign_positions(positions) + end + defp load(socket, request, tracking_active) do assignment = request.assignment participant = assignment && Help.participant?(socket.assigns.current_scope, assignment) @@ -699,6 +757,12 @@ defmodule WhoNeedHelpWeb.RequestLive.Show do defp status_label(:cancelled), do: gettext("Cancelled") defp status_label(value), do: value + defp current_user_confirmed?(scope, request, assignment) do + if Help.requester?(scope, request), + do: not is_nil(assignment.requester_confirmed_at), + else: not is_nil(assignment.helper_confirmed_at) + end + defp visibility_label(:approximate_public), do: gettext("Approximate publicly") defp visibility_label(:hidden), do: gettext("Hidden") defp visibility_label(:exact_for_active_match), do: gettext("Exact only for active match") @@ -892,7 +956,7 @@ defmodule WhoNeedHelpWeb.RequestLive.Show do <.form - :if={!@interaction_blocked} + :if={!@interaction_blocked && @assignment.status in [:accepted, :in_progress]} id="message-form" for={@message_form} phx-submit="send-message" @@ -918,6 +982,14 @@ defmodule WhoNeedHelpWeb.RequestLive.Show do {gettext("Send")} +

+ {if @assignment.status == :completed, + do: gettext("This help request is complete. Chat history is read-only."), + else: gettext("This help request was cancelled. Chat history is read-only.")} +

+
+
+ {gettext("Requester confirmed")} + + {if @assignment.requester_confirmed_at, + do: gettext("Yes"), + else: gettext("Pending")} + +
+
+ {gettext("Helper confirmed")} + + {if @assignment.helper_confirmed_at, + do: gettext("Yes"), + else: gettext("Pending")} + +
+
+ {gettext("Handover code")} + + {if @assignment.handover_verified_at, + do: gettext("Verified"), + else: gettext("Pending")} + +
+
+
+ {gettext("Help completed and verified by both participants.")} +
+
+ {gettext("This match was cancelled. No further handover action is required.")} +
+

+ {gettext("Your completion confirmation is saved.")} +