Merge branch 'feature/pagination' into 'master'
Add pagination to events, groups, partipants to an event and categories See merge request framasoft/mobilizon!26
This commit is contained in:
commit
ccc623bc31
|
@ -20,11 +20,13 @@ defmodule Mobilizon.Actors.Actor do
|
||||||
"""
|
"""
|
||||||
use Ecto.Schema
|
use Ecto.Schema
|
||||||
import Ecto.Changeset
|
import Ecto.Changeset
|
||||||
|
|
||||||
alias Mobilizon.Actors
|
alias Mobilizon.Actors
|
||||||
alias Mobilizon.Actors.{Actor, User, Follower, Member}
|
alias Mobilizon.Actors.{Actor, User, Follower, Member}
|
||||||
alias Mobilizon.Events.Event
|
alias Mobilizon.Events.Event
|
||||||
|
|
||||||
import Ecto.Query
|
import Ecto.Query
|
||||||
|
import Mobilizon.Ecto
|
||||||
alias Mobilizon.Repo
|
alias Mobilizon.Repo
|
||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
@ -232,18 +234,15 @@ defmodule Mobilizon.Actors.Actor do
|
||||||
|
|
||||||
If actor A and C both follow actor B, actor B's followers are A and C
|
If actor A and C both follow actor B, actor B's followers are A and C
|
||||||
"""
|
"""
|
||||||
def get_followers(%Actor{id: actor_id} = _actor, page \\ 1, limit \\ 10) do
|
def get_followers(%Actor{id: actor_id} = _actor, page \\ nil, limit \\ nil) do
|
||||||
start = (page - 1) * limit
|
|
||||||
|
|
||||||
Repo.all(
|
Repo.all(
|
||||||
from(
|
from(
|
||||||
a in Actor,
|
a in Actor,
|
||||||
join: f in Follower,
|
join: f in Follower,
|
||||||
on: a.id == f.actor_id,
|
on: a.id == f.actor_id,
|
||||||
where: f.target_actor_id == ^actor_id,
|
where: f.target_actor_id == ^actor_id
|
||||||
limit: ^limit,
|
|
||||||
offset: ^start
|
|
||||||
)
|
)
|
||||||
|
|> paginate(page, limit)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -252,18 +251,15 @@ defmodule Mobilizon.Actors.Actor do
|
||||||
|
|
||||||
If actor A follows actor B and C, actor A's followings are B and B
|
If actor A follows actor B and C, actor A's followings are B and B
|
||||||
"""
|
"""
|
||||||
def get_followings(%Actor{id: actor_id} = _actor, page \\ 1, limit \\ 10) do
|
def get_followings(%Actor{id: actor_id} = _actor, page \\ nil, limit \\ nil) do
|
||||||
start = (page - 1) * limit
|
|
||||||
|
|
||||||
Repo.all(
|
Repo.all(
|
||||||
from(
|
from(
|
||||||
a in Actor,
|
a in Actor,
|
||||||
join: f in Follower,
|
join: f in Follower,
|
||||||
on: a.id == f.target_actor_id,
|
on: a.id == f.target_actor_id,
|
||||||
where: f.actor_id == ^actor_id,
|
where: f.actor_id == ^actor_id
|
||||||
limit: ^limit,
|
|
||||||
offset: ^start
|
|
||||||
)
|
)
|
||||||
|
|> paginate(page, limit)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
|
@ -4,6 +4,8 @@ defmodule Mobilizon.Actors do
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import Ecto.Query, warn: false
|
import Ecto.Query, warn: false
|
||||||
|
import Mobilizon.Ecto
|
||||||
|
|
||||||
alias Mobilizon.Repo
|
alias Mobilizon.Repo
|
||||||
|
|
||||||
alias Mobilizon.Actors.{Actor, Bot, Member, Follower, User}
|
alias Mobilizon.Actors.{Actor, Bot, Member, Follower, User}
|
||||||
|
@ -150,8 +152,14 @@ defmodule Mobilizon.Actors do
|
||||||
@doc """
|
@doc """
|
||||||
List the groups
|
List the groups
|
||||||
"""
|
"""
|
||||||
def list_groups do
|
def list_groups(page \\ nil, limit \\ nil) do
|
||||||
Repo.all(from(a in Actor, where: a.type == ^:Group))
|
Repo.all(
|
||||||
|
from(
|
||||||
|
a in Actor,
|
||||||
|
where: a.type == ^:Group
|
||||||
|
)
|
||||||
|
|> paginate(page, limit)
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_group_by_name(name) do
|
def get_group_by_name(name) do
|
||||||
|
@ -446,21 +454,18 @@ defmodule Mobilizon.Actors do
|
||||||
Find actors by their name or displayed name
|
Find actors by their name or displayed name
|
||||||
"""
|
"""
|
||||||
@spec find_actors_by_username_or_name(String.t(), integer(), integer()) :: list(Actor.t())
|
@spec find_actors_by_username_or_name(String.t(), integer(), integer()) :: list(Actor.t())
|
||||||
def find_actors_by_username_or_name(username, page \\ 1, limit \\ 10)
|
def find_actors_by_username_or_name(username, page \\ nil, limit \\ nil)
|
||||||
def find_actors_by_username_or_name("", _page, _limit), do: []
|
def find_actors_by_username_or_name("", _page, _limit), do: []
|
||||||
|
|
||||||
def find_actors_by_username_or_name(username, page, limit) do
|
def find_actors_by_username_or_name(username, page, limit) do
|
||||||
start = (page - 1) * limit
|
|
||||||
|
|
||||||
Repo.all(
|
Repo.all(
|
||||||
from(
|
from(
|
||||||
a in Actor,
|
a in Actor,
|
||||||
limit: ^limit,
|
|
||||||
offset: ^start,
|
|
||||||
where:
|
where:
|
||||||
ilike(a.preferred_username, ^like_sanitize(username)) or
|
ilike(a.preferred_username, ^like_sanitize(username)) or
|
||||||
ilike(a.name, ^like_sanitize(username))
|
ilike(a.name, ^like_sanitize(username))
|
||||||
)
|
)
|
||||||
|
|> paginate(page, limit)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
|
34
lib/mobilizon/ecto.ex
Normal file
34
lib/mobilizon/ecto.ex
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
defmodule Mobilizon.Ecto do
|
||||||
|
@moduledoc """
|
||||||
|
Mobilizon Ecto utils
|
||||||
|
"""
|
||||||
|
|
||||||
|
import Ecto.Query, warn: false
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Add limit and offset to the query
|
||||||
|
"""
|
||||||
|
def paginate(query, page \\ 1, size \\ 10)
|
||||||
|
def paginate(query, page, _size) when is_nil(page), do: paginate(query)
|
||||||
|
def paginate(query, page, size) when is_nil(size), do: paginate(query, page)
|
||||||
|
|
||||||
|
def paginate(query, page, size) do
|
||||||
|
from(query,
|
||||||
|
limit: ^size,
|
||||||
|
offset: ^((page - 1) * size)
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
def increment_slug(slug) do
|
||||||
|
case List.pop_at(String.split(slug, "-"), -1) do
|
||||||
|
{nil, _} ->
|
||||||
|
slug
|
||||||
|
|
||||||
|
{suffix, slug_parts} ->
|
||||||
|
case Integer.parse(suffix) do
|
||||||
|
{id, _} -> Enum.join(slug_parts, "-") <> "-" <> Integer.to_string(id + 1)
|
||||||
|
:error -> slug <> "-1"
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
|
@ -4,6 +4,7 @@ defmodule Mobilizon.Events do
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import Ecto.Query, warn: false
|
import Ecto.Query, warn: false
|
||||||
|
import Mobilizon.Ecto
|
||||||
alias Mobilizon.Repo
|
alias Mobilizon.Repo
|
||||||
|
|
||||||
alias Mobilizon.Events.{Event, Comment, Participant}
|
alias Mobilizon.Events.{Event, Comment, Participant}
|
||||||
|
@ -18,16 +19,12 @@ defmodule Mobilizon.Events do
|
||||||
queryable
|
queryable
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_events_for_actor(%Actor{id: actor_id} = _actor, page \\ 1, limit \\ 10) do
|
def get_events_for_actor(%Actor{id: actor_id} = _actor, page \\ nil, limit \\ nil) do
|
||||||
start = (page - 1) * limit
|
|
||||||
|
|
||||||
query =
|
query =
|
||||||
from(
|
from(
|
||||||
e in Event,
|
e in Event,
|
||||||
where: e.organizer_actor_id == ^actor_id,
|
where: e.organizer_actor_id == ^actor_id,
|
||||||
limit: ^limit,
|
|
||||||
order_by: [desc: :id],
|
order_by: [desc: :id],
|
||||||
offset: ^start,
|
|
||||||
preload: [
|
preload: [
|
||||||
:organizer_actor,
|
:organizer_actor,
|
||||||
:category,
|
:category,
|
||||||
|
@ -38,6 +35,7 @@ defmodule Mobilizon.Events do
|
||||||
:physical_address
|
:physical_address
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|> paginate(page, limit)
|
||||||
|
|
||||||
events = Repo.all(query)
|
events = Repo.all(query)
|
||||||
|
|
||||||
|
@ -186,15 +184,10 @@ defmodule Mobilizon.Events do
|
||||||
[%Event{}, ...]
|
[%Event{}, ...]
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def list_events(page \\ 1, limit \\ 10) do
|
def list_events(page \\ nil, limit \\ nil) do
|
||||||
start = (page - 1) * limit
|
|
||||||
|
|
||||||
query =
|
query =
|
||||||
from(e in Event,
|
from(e in Event, preload: [:organizer_actor])
|
||||||
limit: ^limit,
|
|> paginate(page, limit)
|
||||||
offset: ^start,
|
|
||||||
preload: [:organizer_actor]
|
|
||||||
)
|
|
||||||
|
|
||||||
Repo.all(query)
|
Repo.all(query)
|
||||||
end
|
end
|
||||||
|
@ -202,20 +195,18 @@ defmodule Mobilizon.Events do
|
||||||
@doc """
|
@doc """
|
||||||
Find events by name
|
Find events by name
|
||||||
"""
|
"""
|
||||||
def find_events_by_name(name, page \\ 1, limit \\ 10)
|
def find_events_by_name(name, page \\ nil, limit \\ nil)
|
||||||
def find_events_by_name("", page, limit), do: list_events(page, limit)
|
def find_events_by_name("", page, limit), do: list_events(page, limit)
|
||||||
|
|
||||||
def find_events_by_name(name, page, limit) do
|
def find_events_by_name(name, page, limit) do
|
||||||
name = String.trim(name)
|
name = String.trim(name)
|
||||||
start = (page - 1) * limit
|
|
||||||
|
|
||||||
query =
|
query =
|
||||||
from(e in Event,
|
from(e in Event,
|
||||||
limit: ^limit,
|
|
||||||
offset: ^start,
|
|
||||||
where: ilike(e.title, ^like_sanitize(name)),
|
where: ilike(e.title, ^like_sanitize(name)),
|
||||||
preload: [:organizer_actor]
|
preload: [:organizer_actor]
|
||||||
)
|
)
|
||||||
|
|> paginate(page, limit)
|
||||||
|
|
||||||
Repo.all(query)
|
Repo.all(query)
|
||||||
end
|
end
|
||||||
|
@ -309,8 +300,11 @@ defmodule Mobilizon.Events do
|
||||||
[%Category{}, ...]
|
[%Category{}, ...]
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def list_categories do
|
def list_categories(page \\ nil, limit \\ nil) do
|
||||||
Repo.all(Category)
|
Repo.all(
|
||||||
|
Category
|
||||||
|
|> paginate(page, limit)
|
||||||
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
@ -519,7 +513,7 @@ defmodule Mobilizon.Events do
|
||||||
[%Participant{}, ...]
|
[%Participant{}, ...]
|
||||||
|
|
||||||
"""
|
"""
|
||||||
def list_participants_for_event(uuid) do
|
def list_participants_for_event(uuid, page \\ nil, limit \\ nil) do
|
||||||
Repo.all(
|
Repo.all(
|
||||||
from(
|
from(
|
||||||
p in Participant,
|
p in Participant,
|
||||||
|
@ -528,6 +522,7 @@ defmodule Mobilizon.Events do
|
||||||
where: e.uuid == ^uuid,
|
where: e.uuid == ^uuid,
|
||||||
preload: [:actor]
|
preload: [:actor]
|
||||||
)
|
)
|
||||||
|
|> paginate(page, limit)
|
||||||
)
|
)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -846,16 +841,12 @@ defmodule Mobilizon.Events do
|
||||||
Repo.all(Comment)
|
Repo.all(Comment)
|
||||||
end
|
end
|
||||||
|
|
||||||
def get_comments_for_actor(%Actor{id: actor_id}, page \\ 1, limit \\ 10) do
|
def get_comments_for_actor(%Actor{id: actor_id}, page \\ nil, limit \\ nil) do
|
||||||
start = (page - 1) * limit
|
|
||||||
|
|
||||||
query =
|
query =
|
||||||
from(
|
from(
|
||||||
c in Comment,
|
c in Comment,
|
||||||
where: c.actor_id == ^actor_id,
|
where: c.actor_id == ^actor_id,
|
||||||
limit: ^limit,
|
|
||||||
order_by: [desc: :id],
|
order_by: [desc: :id],
|
||||||
offset: ^start,
|
|
||||||
preload: [
|
preload: [
|
||||||
:actor,
|
:actor,
|
||||||
:in_reply_to_comment,
|
:in_reply_to_comment,
|
||||||
|
@ -863,6 +854,7 @@ defmodule Mobilizon.Events do
|
||||||
:event
|
:event
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|> paginate(page, limit)
|
||||||
|
|
||||||
comments = Repo.all(query)
|
comments = Repo.all(query)
|
||||||
|
|
||||||
|
|
|
@ -25,7 +25,7 @@ defmodule Mobilizon.Events.Tag.TitleSlug do
|
||||||
|
|
||||||
_tag ->
|
_tag ->
|
||||||
slug
|
slug
|
||||||
|> Mobilizon.Slug.increment_slug()
|
|> Mobilizon.Ecto.increment_slug()
|
||||||
|> build_unique_slug(changeset)
|
|> build_unique_slug(changeset)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -1,17 +0,0 @@
|
||||||
defmodule Mobilizon.Slug do
|
|
||||||
@moduledoc """
|
|
||||||
Common functions for slug generation
|
|
||||||
"""
|
|
||||||
def increment_slug(slug) do
|
|
||||||
case List.pop_at(String.split(slug, "-"), -1) do
|
|
||||||
{nil, _} ->
|
|
||||||
slug
|
|
||||||
|
|
||||||
{suffix, slug_parts} ->
|
|
||||||
case Integer.parse(suffix) do
|
|
||||||
{id, _} -> Enum.join(slug_parts, "-") <> "-" <> Integer.to_string(id + 1)
|
|
||||||
:error -> slug <> "-1"
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
||||||
end
|
|
|
@ -2,9 +2,9 @@ defmodule MobilizonWeb.Resolvers.Category do
|
||||||
require Logger
|
require Logger
|
||||||
alias Mobilizon.Actors.User
|
alias Mobilizon.Actors.User
|
||||||
|
|
||||||
def list_categories(_parent, _args, _resolution) do
|
def list_categories(_parent, %{page: page, limit: limit}, _resolution) do
|
||||||
categories =
|
categories =
|
||||||
Mobilizon.Events.list_categories()
|
Mobilizon.Events.list_categories(page, limit)
|
||||||
|> Enum.map(fn category ->
|
|> Enum.map(fn category ->
|
||||||
urls = MobilizonWeb.Uploaders.Category.urls({category.picture, category})
|
urls = MobilizonWeb.Uploaders.Category.urls({category.picture, category})
|
||||||
Map.put(category, :picture, %{url: urls.original, url_thumbnail: urls.thumb})
|
Map.put(category, :picture, %{url: urls.original, url_thumbnail: urls.thumb})
|
||||||
|
|
|
@ -2,8 +2,8 @@ defmodule MobilizonWeb.Resolvers.Event do
|
||||||
alias Mobilizon.Service.ActivityPub
|
alias Mobilizon.Service.ActivityPub
|
||||||
alias Mobilizon.Actors
|
alias Mobilizon.Actors
|
||||||
|
|
||||||
def list_events(_parent, _args, _resolution) do
|
def list_events(_parent, %{page: page, limit: limit}, _resolution) do
|
||||||
{:ok, Mobilizon.Events.list_events()}
|
{:ok, Mobilizon.Events.list_events(page, limit)}
|
||||||
end
|
end
|
||||||
|
|
||||||
def find_event(_parent, %{uuid: uuid}, _resolution) do
|
def find_event(_parent, %{uuid: uuid}, _resolution) do
|
||||||
|
@ -26,8 +26,8 @@ defmodule MobilizonWeb.Resolvers.Event do
|
||||||
@doc """
|
@doc """
|
||||||
List participants for event (through an event request)
|
List participants for event (through an event request)
|
||||||
"""
|
"""
|
||||||
def list_participants_for_event(%{uuid: uuid}, _args, _resolution) do
|
def list_participants_for_event(%{uuid: uuid}, %{page: page, limit: limit}, _resolution) do
|
||||||
{:ok, Mobilizon.Events.list_participants_for_event(uuid)}
|
{:ok, Mobilizon.Events.list_participants_for_event(uuid, page, limit)}
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
|
|
@ -20,8 +20,8 @@ defmodule MobilizonWeb.Resolvers.Group do
|
||||||
@doc """
|
@doc """
|
||||||
Lists all groups
|
Lists all groups
|
||||||
"""
|
"""
|
||||||
def list_groups(_parent, _args, _resolution) do
|
def list_groups(_parent, %{page: page, limit: limit}, _resolution) do
|
||||||
{:ok, Actors.list_groups()}
|
{:ok, Actors.list_groups(page, limit)}
|
||||||
end
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
|
|
|
@ -322,7 +322,7 @@ defmodule MobilizonWeb.Schema do
|
||||||
end
|
end
|
||||||
|
|
||||||
@desc """
|
@desc """
|
||||||
Represents an actor's follower
|
Represents an actor's follower
|
||||||
"""
|
"""
|
||||||
object :follower do
|
object :follower do
|
||||||
field(:target_actor, :actor, description: "What or who the profile follows")
|
field(:target_actor, :actor, description: "What or who the profile follows")
|
||||||
|
@ -395,11 +395,15 @@ defmodule MobilizonWeb.Schema do
|
||||||
query do
|
query do
|
||||||
@desc "Get all events"
|
@desc "Get all events"
|
||||||
field :events, list_of(:event) do
|
field :events, list_of(:event) do
|
||||||
|
arg(:page, :integer, default_value: 1)
|
||||||
|
arg(:limit, :integer, default_value: 10)
|
||||||
resolve(&Resolvers.Event.list_events/3)
|
resolve(&Resolvers.Event.list_events/3)
|
||||||
end
|
end
|
||||||
|
|
||||||
@desc "Get all groups"
|
@desc "Get all groups"
|
||||||
field :groups, list_of(:group) do
|
field :groups, list_of(:group) do
|
||||||
|
arg(:page, :integer, default_value: 1)
|
||||||
|
arg(:limit, :integer, default_value: 10)
|
||||||
resolve(&Resolvers.Group.list_groups/3)
|
resolve(&Resolvers.Group.list_groups/3)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -420,6 +424,8 @@ defmodule MobilizonWeb.Schema do
|
||||||
@desc "Get all participants for an event uuid"
|
@desc "Get all participants for an event uuid"
|
||||||
field :participants, list_of(:participant) do
|
field :participants, list_of(:participant) do
|
||||||
arg(:uuid, non_null(:uuid))
|
arg(:uuid, non_null(:uuid))
|
||||||
|
arg(:page, :integer, default_value: 1)
|
||||||
|
arg(:limit, :integer, default_value: 10)
|
||||||
resolve(&Resolvers.Event.list_participants_for_event/3)
|
resolve(&Resolvers.Event.list_participants_for_event/3)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -453,6 +459,8 @@ defmodule MobilizonWeb.Schema do
|
||||||
|
|
||||||
@desc "Get the list of categories"
|
@desc "Get the list of categories"
|
||||||
field :categories, non_null(list_of(:category)) do
|
field :categories, non_null(list_of(:category)) do
|
||||||
|
arg(:page, :integer, default_value: 1)
|
||||||
|
arg(:limit, :integer, default_value: 10)
|
||||||
resolve(&Resolvers.Category.list_categories/3)
|
resolve(&Resolvers.Category.list_categories/3)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -361,7 +361,9 @@ defmodule Mobilizon.Service.ActivityPub do
|
||||||
Return all public activities (events & comments) for an actor
|
Return all public activities (events & comments) for an actor
|
||||||
"""
|
"""
|
||||||
@spec fetch_public_activities_for_actor(Actor.t(), integer(), integer()) :: {list(), integer()}
|
@spec fetch_public_activities_for_actor(Actor.t(), integer(), integer()) :: {list(), integer()}
|
||||||
def fetch_public_activities_for_actor(%Actor{} = actor, page \\ 1, limit \\ 10) do
|
def fetch_public_activities_for_actor(actor, page \\ nil, limit \\ nil)
|
||||||
|
|
||||||
|
def fetch_public_activities_for_actor(%Actor{} = actor, page, limit) do
|
||||||
case actor.type do
|
case actor.type do
|
||||||
:Person ->
|
:Person ->
|
||||||
{:ok, events, total_events} = Events.get_events_for_actor(actor, page, limit)
|
{:ok, events, total_events} = Events.get_events_for_actor(actor, page, limit)
|
||||||
|
|
Loading…
Reference in a new issue