Merge branch 'fixes' into 'main'
Various fixes Closes #997 See merge request framasoft/mobilizon!1199
This commit is contained in:
commit
0fac23cc4b
@ -212,7 +212,8 @@ config :mobilizon, :activitypub,
|
|||||||
# One day
|
# One day
|
||||||
actor_stale_period: 3_600 * 48,
|
actor_stale_period: 3_600 * 48,
|
||||||
actor_key_rotation_delay: 3_600 * 48,
|
actor_key_rotation_delay: 3_600 * 48,
|
||||||
sign_object_fetches: true
|
sign_object_fetches: true,
|
||||||
|
stale_actor_search_exclusion_after: 3_600 * 24 * 7
|
||||||
|
|
||||||
config :mobilizon, Mobilizon.Service.Geospatial, service: Mobilizon.Service.Geospatial.Nominatim
|
config :mobilizon, Mobilizon.Service.Geospatial, service: Mobilizon.Service.Geospatial.Nominatim
|
||||||
|
|
||||||
|
@ -5,33 +5,48 @@
|
|||||||
:placeholder="$t('Filter by profile or group name')"
|
:placeholder="$t('Filter by profile or group name')"
|
||||||
v-model="actorFilter"
|
v-model="actorFilter"
|
||||||
/>
|
/>
|
||||||
<b-radio-button
|
<transition-group
|
||||||
v-model="selectedActor"
|
tag="ul"
|
||||||
:native-value="availableActor"
|
class="grid grid-cols-1 gap-y-3 m-5 max-w-md mx-auto"
|
||||||
class="list-item"
|
enter-active-class="duration-300 ease-out"
|
||||||
v-for="availableActor in actualFilteredAvailableActors"
|
enter-from-class="transform opacity-0"
|
||||||
:key="availableActor.id"
|
enter-to-class="opacity-100"
|
||||||
|
leave-active-class="duration-200 ease-in"
|
||||||
|
leave-from-class="opacity-100"
|
||||||
|
leave-to-class="transform opacity-0"
|
||||||
>
|
>
|
||||||
<div class="media" dir="auto">
|
<li
|
||||||
<figure class="image is-48x48" v-if="availableActor.avatar">
|
class="relative focus-within:shadow-lg"
|
||||||
<img
|
v-for="availableActor in actualFilteredAvailableActors"
|
||||||
class="image is-rounded"
|
:key="availableActor.id"
|
||||||
:src="availableActor.avatar.url"
|
>
|
||||||
alt=""
|
<input
|
||||||
/>
|
class="sr-only peer"
|
||||||
</figure>
|
type="radio"
|
||||||
<b-icon
|
:value="availableActor"
|
||||||
class="media-left"
|
name="availableActors"
|
||||||
v-else
|
v-model="selectedActor"
|
||||||
size="is-large"
|
:id="`availableActor-${availableActor.id}`"
|
||||||
icon="account-circle"
|
|
||||||
/>
|
/>
|
||||||
<div class="media-content">
|
<label
|
||||||
<h3>{{ availableActor.name }}</h3>
|
class="flex flex-wrap p-3 bg-white border border-gray-300 rounded-lg cursor-pointer hover:bg-gray-50 peer-checked:ring-primary peer-checked:ring-2 peer-checked:border-transparent"
|
||||||
<small>{{ `@${availableActor.preferredUsername}` }}</small>
|
:for="`availableActor-${availableActor.id}`"
|
||||||
</div>
|
>
|
||||||
</div>
|
<figure class="image is-48x48" v-if="availableActor.avatar">
|
||||||
</b-radio-button>
|
<img
|
||||||
|
class="image is-rounded"
|
||||||
|
:src="availableActor.avatar.url"
|
||||||
|
alt=""
|
||||||
|
/>
|
||||||
|
</figure>
|
||||||
|
<b-icon v-else size="is-large" icon="account-circle" />
|
||||||
|
<div>
|
||||||
|
<h3>{{ availableActor.name }}</h3>
|
||||||
|
<small>{{ `@${availableActor.preferredUsername}` }}</small>
|
||||||
|
</div>
|
||||||
|
</label>
|
||||||
|
</li>
|
||||||
|
</transition-group>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script lang="ts">
|
<script lang="ts">
|
||||||
|
@ -1,5 +1,8 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="organizer-picker" v-if="selectedActor">
|
<div
|
||||||
|
class="bg-white border border-gray-300 rounded-lg cursor-pointer"
|
||||||
|
v-if="selectedActor"
|
||||||
|
>
|
||||||
<!-- If we have a current actor (inline) -->
|
<!-- If we have a current actor (inline) -->
|
||||||
<div
|
<div
|
||||||
v-if="inline && selectedActor.id"
|
v-if="inline && selectedActor.id"
|
||||||
@ -69,7 +72,8 @@
|
|||||||
<p>{{ $t("Add a contact") }}</p>
|
<p>{{ $t("Add a contact") }}</p>
|
||||||
<b-input
|
<b-input
|
||||||
:placeholder="$t('Filter by name')"
|
:placeholder="$t('Filter by name')"
|
||||||
v-model="contactFilter"
|
:value="contactFilter"
|
||||||
|
@input="debounceSetFilterByName"
|
||||||
dir="auto"
|
dir="auto"
|
||||||
/>
|
/>
|
||||||
<div v-if="actorMembers.length > 0">
|
<div v-if="actorMembers.length > 0">
|
||||||
@ -144,11 +148,12 @@ import EmptyContent from "../Utils/EmptyContent.vue";
|
|||||||
import {
|
import {
|
||||||
CURRENT_ACTOR_CLIENT,
|
CURRENT_ACTOR_CLIENT,
|
||||||
IDENTITIES,
|
IDENTITIES,
|
||||||
LOGGED_USER_MEMBERSHIPS,
|
PERSON_GROUP_MEMBERSHIPS,
|
||||||
} from "../../graphql/actor";
|
} from "../../graphql/actor";
|
||||||
import { Paginate } from "../../types/paginate";
|
import { Paginate } from "../../types/paginate";
|
||||||
import { GROUP_MEMBERS } from "@/graphql/member";
|
import { GROUP_MEMBERS } from "@/graphql/member";
|
||||||
import { ActorType, MemberRole } from "@/types/enums";
|
import { ActorType, MemberRole } from "@/types/enums";
|
||||||
|
import debounce from "lodash/debounce";
|
||||||
|
|
||||||
const MEMBER_ROLES = [
|
const MEMBER_ROLES = [
|
||||||
MemberRole.CREATOR,
|
MemberRole.CREATOR,
|
||||||
@ -179,15 +184,17 @@ const MEMBER_ROLES = [
|
|||||||
},
|
},
|
||||||
},
|
},
|
||||||
currentActor: CURRENT_ACTOR_CLIENT,
|
currentActor: CURRENT_ACTOR_CLIENT,
|
||||||
userMemberships: {
|
personMemberships: {
|
||||||
query: LOGGED_USER_MEMBERSHIPS,
|
query: PERSON_GROUP_MEMBERSHIPS,
|
||||||
variables() {
|
variables() {
|
||||||
return {
|
return {
|
||||||
|
id: this.currentActor?.id,
|
||||||
page: 1,
|
page: 1,
|
||||||
limit: 10,
|
limit: 10,
|
||||||
|
groupId: this.$route.query?.actorId,
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
update: (data) => data.loggedUser.memberships,
|
update: (data) => data.person.memberships,
|
||||||
},
|
},
|
||||||
identities: IDENTITIES,
|
identities: IDENTITIES,
|
||||||
},
|
},
|
||||||
@ -197,6 +204,9 @@ export default class OrganizerPickerWrapper extends Vue {
|
|||||||
|
|
||||||
@Prop({ default: true, type: Boolean }) inline!: boolean;
|
@Prop({ default: true, type: Boolean }) inline!: boolean;
|
||||||
|
|
||||||
|
@Prop({ type: Array, required: false, default: () => [] })
|
||||||
|
contacts!: IActor[];
|
||||||
|
|
||||||
currentActor!: IPerson;
|
currentActor!: IPerson;
|
||||||
|
|
||||||
identities!: IPerson[];
|
identities!: IPerson[];
|
||||||
@ -207,13 +217,17 @@ export default class OrganizerPickerWrapper extends Vue {
|
|||||||
|
|
||||||
usernameWithDomain = usernameWithDomain;
|
usernameWithDomain = usernameWithDomain;
|
||||||
|
|
||||||
@Prop({ type: Array, required: false, default: () => [] })
|
|
||||||
contacts!: IActor[];
|
|
||||||
members: Paginate<IMember> = { elements: [], total: 0 };
|
members: Paginate<IMember> = { elements: [], total: 0 };
|
||||||
|
|
||||||
membersPage = 1;
|
membersPage = 1;
|
||||||
|
|
||||||
userMemberships: Paginate<IMember> = { elements: [], total: 0 };
|
personMemberships: Paginate<IMember> = { elements: [], total: 0 };
|
||||||
|
|
||||||
|
data(): Record<string, unknown> {
|
||||||
|
return {
|
||||||
|
debounceSetFilterByName: debounce(this.setContactFilter, 1000),
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
get actualContacts(): (string | undefined)[] {
|
get actualContacts(): (string | undefined)[] {
|
||||||
return this.contacts.map(({ id }) => id);
|
return this.contacts.map(({ id }) => id);
|
||||||
@ -226,15 +240,17 @@ export default class OrganizerPickerWrapper extends Vue {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Watch("userMemberships")
|
setContactFilter(contactFilter: string) {
|
||||||
|
this.contactFilter = contactFilter;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Watch("personMemberships")
|
||||||
setInitialActor(): void {
|
setInitialActor(): void {
|
||||||
if (this.$route.query?.actorId) {
|
if (
|
||||||
const actorId = this.$route.query?.actorId as string;
|
this.personMemberships?.elements[0]?.parent?.id ===
|
||||||
const actor = this.userMemberships.elements.find(
|
this.$route.query?.actorId
|
||||||
({ parent: { id }, role }) =>
|
) {
|
||||||
actorId === id && MEMBER_ROLES.includes(role)
|
this.selectedActor = this.personMemberships?.elements[0]?.parent;
|
||||||
)?.parent as IActor;
|
|
||||||
this.selectedActor = actor;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -276,7 +292,7 @@ export default class OrganizerPickerWrapper extends Vue {
|
|||||||
actor.preferredUsername.toLowerCase(),
|
actor.preferredUsername.toLowerCase(),
|
||||||
actor.name?.toLowerCase(),
|
actor.name?.toLowerCase(),
|
||||||
actor.domain?.toLowerCase(),
|
actor.domain?.toLowerCase(),
|
||||||
].some((match) => match?.includes(this.contactFilter.toLowerCase()));
|
];
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -351,6 +351,30 @@ export const PERSON_STATUS_GROUP = gql`
|
|||||||
${ACTOR_FRAGMENT}
|
${ACTOR_FRAGMENT}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const PERSON_GROUP_MEMBERSHIPS = gql`
|
||||||
|
query PersonGroupMemberships($id: ID!, $groupId: ID!) {
|
||||||
|
person(id: $id) {
|
||||||
|
id
|
||||||
|
memberships(groupId: $groupId) {
|
||||||
|
total
|
||||||
|
elements {
|
||||||
|
id
|
||||||
|
role
|
||||||
|
parent {
|
||||||
|
...ActorFragment
|
||||||
|
}
|
||||||
|
invitedBy {
|
||||||
|
...ActorFragment
|
||||||
|
}
|
||||||
|
insertedAt
|
||||||
|
updatedAt
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${ACTOR_FRAGMENT}
|
||||||
|
`;
|
||||||
|
|
||||||
export const GROUP_MEMBERSHIP_SUBSCRIPTION_CHANGED = gql`
|
export const GROUP_MEMBERSHIP_SUBSCRIPTION_CHANGED = gql`
|
||||||
subscription GroupMembershipSubscriptionChanged(
|
subscription GroupMembershipSubscriptionChanged(
|
||||||
$actorId: ID!
|
$actorId: ID!
|
||||||
|
@ -226,6 +226,15 @@ export const FETCH_GROUP = gql`
|
|||||||
${RESOURCE_METADATA_BASIC_FIELDS_FRAGMENT}
|
${RESOURCE_METADATA_BASIC_FIELDS_FRAGMENT}
|
||||||
`;
|
`;
|
||||||
|
|
||||||
|
export const FETCH_GROUP_BY_ID = gql`
|
||||||
|
query FetchGroupById($id: ID!) {
|
||||||
|
groupById(id: $name) {
|
||||||
|
...GroupFullFields
|
||||||
|
}
|
||||||
|
}
|
||||||
|
${GROUP_FIELDS_FRAGMENTS}
|
||||||
|
`;
|
||||||
|
|
||||||
export const GET_GROUP = gql`
|
export const GET_GROUP = gql`
|
||||||
query GetGroup(
|
query GetGroup(
|
||||||
$id: ID!
|
$id: ID!
|
||||||
|
@ -95,7 +95,7 @@
|
|||||||
>
|
>
|
||||||
<b-button
|
<b-button
|
||||||
size="is-small"
|
size="is-small"
|
||||||
v-if="!user.confirmedAt || !user.disabled"
|
v-if="!user.confirmedAt || user.disabled"
|
||||||
@click="isConfirmationModalActive = true"
|
@click="isConfirmationModalActive = true"
|
||||||
type="is-text"
|
type="is-text"
|
||||||
icon-left="check"
|
icon-left="check"
|
||||||
|
@ -49,7 +49,8 @@ defmodule Mobilizon.GraphQL.API.Search do
|
|||||||
location: Map.get(args, :location),
|
location: Map.get(args, :location),
|
||||||
minimum_visibility: Map.get(args, :minimum_visibility, :public),
|
minimum_visibility: Map.get(args, :minimum_visibility, :public),
|
||||||
current_actor_id: Map.get(args, :current_actor_id),
|
current_actor_id: Map.get(args, :current_actor_id),
|
||||||
exclude_my_groups: Map.get(args, :exclude_my_groups, false)
|
exclude_my_groups: Map.get(args, :exclude_my_groups, false),
|
||||||
|
exclude_stale_actors: true
|
||||||
],
|
],
|
||||||
page,
|
page,
|
||||||
limit
|
limit
|
||||||
|
@ -16,15 +16,15 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
|||||||
|
|
||||||
require Logger
|
require Logger
|
||||||
|
|
||||||
|
@doc """
|
||||||
|
Find a group
|
||||||
|
"""
|
||||||
@spec find_group(
|
@spec find_group(
|
||||||
any,
|
any,
|
||||||
%{:preferred_username => binary, optional(any) => any},
|
%{:preferred_username => binary, optional(any) => any},
|
||||||
Absinthe.Resolution.t()
|
Absinthe.Resolution.t()
|
||||||
) ::
|
) ::
|
||||||
{:error, :group_not_found} | {:ok, Actor.t()}
|
{:error, :group_not_found} | {:ok, Actor.t()}
|
||||||
@doc """
|
|
||||||
Find a group
|
|
||||||
"""
|
|
||||||
def find_group(
|
def find_group(
|
||||||
parent,
|
parent,
|
||||||
%{preferred_username: name} = args,
|
%{preferred_username: name} = args,
|
||||||
@ -45,7 +45,8 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
|||||||
{:ok, %Actor{}} ->
|
{:ok, %Actor{}} ->
|
||||||
{:error, :group_not_found}
|
{:error, :group_not_found}
|
||||||
|
|
||||||
{:error, _err} ->
|
{:error, err} ->
|
||||||
|
Logger.debug("Unable to find group, #{inspect(err)}")
|
||||||
{:error, :group_not_found}
|
{:error, :group_not_found}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
@ -59,11 +60,30 @@ defmodule Mobilizon.GraphQL.Resolvers.Group do
|
|||||||
{:ok, %Actor{}} ->
|
{:ok, %Actor{}} ->
|
||||||
{:error, :group_not_found}
|
{:error, :group_not_found}
|
||||||
|
|
||||||
{:error, _err} ->
|
{:error, err} ->
|
||||||
|
Logger.debug("Unable to find group, #{inspect(err)}")
|
||||||
{:error, :group_not_found}
|
{:error, :group_not_found}
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
def find_group_by_id(_parent, %{id: id} = args, %{
|
||||||
|
context: %{
|
||||||
|
current_actor: %Actor{id: actor_id}
|
||||||
|
}
|
||||||
|
}) do
|
||||||
|
with %Actor{suspended: false, id: group_id} = group <- Actors.get_actor_with_preload(id),
|
||||||
|
true <- Actors.is_member?(actor_id, group_id) do
|
||||||
|
{:ok, group}
|
||||||
|
else
|
||||||
|
_ ->
|
||||||
|
{:error, :group_not_found}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
def find_group_by_id(_parent, _args, _resolution) do
|
||||||
|
{:error, :group_not_found}
|
||||||
|
end
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Get a group
|
Get a group
|
||||||
"""
|
"""
|
||||||
|
@ -358,11 +358,11 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
|||||||
Returns this person's group memberships
|
Returns this person's group memberships
|
||||||
"""
|
"""
|
||||||
@spec person_memberships(Actor.t(), map(), map()) :: {:ok, Page.t()} | {:error, String.t()}
|
@spec person_memberships(Actor.t(), map(), map()) :: {:ok, Page.t()} | {:error, String.t()}
|
||||||
def person_memberships(%Actor{id: actor_id} = person, %{group: group}, %{
|
def person_memberships(%Actor{id: actor_id} = person, args, %{
|
||||||
context: %{current_user: %User{} = user}
|
context: %{current_user: %User{} = user}
|
||||||
}) do
|
}) do
|
||||||
if user_can_access_person_details?(person, user) do
|
if user_can_access_person_details?(person, user) do
|
||||||
with {:group, %Actor{id: group_id}} <- {:group, Actors.get_actor_by_name(group, :Group)},
|
with {:group, %Actor{id: group_id}} <- {:group, group_from_args(args)},
|
||||||
{:ok, %Member{} = membership} <- Actors.get_member(actor_id, group_id) do
|
{:ok, %Member{} = membership} <- Actors.get_member(actor_id, group_id) do
|
||||||
{:ok,
|
{:ok,
|
||||||
%Page{
|
%Page{
|
||||||
@ -373,6 +373,21 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
|||||||
{:error, :member_not_found} ->
|
{:error, :member_not_found} ->
|
||||||
{:ok, %Page{total: 0, elements: []}}
|
{:ok, %Page{total: 0, elements: []}}
|
||||||
|
|
||||||
|
{:group, :none} ->
|
||||||
|
with {:can_get_memberships, true} <-
|
||||||
|
{:can_get_memberships, user_can_access_person_details?(person, user)},
|
||||||
|
memberships <-
|
||||||
|
Actors.list_members_for_actor(
|
||||||
|
person,
|
||||||
|
Map.get(args, :page, 1),
|
||||||
|
Map.get(args, :limit, 10)
|
||||||
|
) do
|
||||||
|
{:ok, memberships}
|
||||||
|
else
|
||||||
|
{:can_get_memberships, _} ->
|
||||||
|
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
|
||||||
|
end
|
||||||
|
|
||||||
{:group, nil} ->
|
{:group, nil} ->
|
||||||
{:error, :group_not_found}
|
{:error, :group_not_found}
|
||||||
end
|
end
|
||||||
@ -381,23 +396,6 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
|||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def person_memberships(
|
|
||||||
%Actor{} = person,
|
|
||||||
%{page: page, limit: limit},
|
|
||||||
%{
|
|
||||||
context: %{current_user: %User{} = user}
|
|
||||||
}
|
|
||||||
) do
|
|
||||||
with {:can_get_memberships, true} <-
|
|
||||||
{:can_get_memberships, user_can_access_person_details?(person, user)},
|
|
||||||
memberships <- Actors.list_members_for_actor(person, page, limit) do
|
|
||||||
{:ok, memberships}
|
|
||||||
else
|
|
||||||
{:can_get_memberships, _} ->
|
|
||||||
{:error, dgettext("errors", "Profile is not owned by authenticated user")}
|
|
||||||
end
|
|
||||||
end
|
|
||||||
|
|
||||||
@doc """
|
@doc """
|
||||||
Returns this person's group follows
|
Returns this person's group follows
|
||||||
"""
|
"""
|
||||||
@ -498,4 +496,17 @@ defmodule Mobilizon.GraphQL.Resolvers.Person do
|
|||||||
do: actor_user_id == user_id
|
do: actor_user_id == user_id
|
||||||
|
|
||||||
defp user_can_access_person_details?(_, _), do: false
|
defp user_can_access_person_details?(_, _), do: false
|
||||||
|
|
||||||
|
@spec group_from_args(map()) :: Actor.t() | nil
|
||||||
|
defp group_from_args(%{group: group}) do
|
||||||
|
Actors.get_actor_by_name(group, :Group)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp group_from_args(%{group_id: group_id}) do
|
||||||
|
Actors.get_actor(group_id)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp group_from_args(_) do
|
||||||
|
:none
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
@ -244,6 +244,13 @@ defmodule Mobilizon.GraphQL.Schema.Actors.GroupType do
|
|||||||
|
|
||||||
resolve(&Group.find_group/3)
|
resolve(&Group.find_group/3)
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@desc "Get a group by its preferred username"
|
||||||
|
field :group_by_id, :group do
|
||||||
|
arg(:id, non_null(:id), description: "The group local ID")
|
||||||
|
|
||||||
|
resolve(&Group.find_group_by_id/3)
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
object :group_mutations do
|
object :group_mutations do
|
||||||
|
@ -88,11 +88,12 @@ defmodule Mobilizon.GraphQL.Schema.Actors.PersonType do
|
|||||||
resolve(&Person.person_participations/3)
|
resolve(&Person.person_participations/3)
|
||||||
end
|
end
|
||||||
|
|
||||||
@desc "The list of group this person is member of"
|
@desc "The list of groups this person is member of"
|
||||||
field(:memberships, :paginated_member_list,
|
field(:memberships, :paginated_member_list,
|
||||||
description: "The list of group this person is member of"
|
description: "The list of group this person is member of"
|
||||||
) do
|
) do
|
||||||
arg(:group, :string, description: "Filter by group federated username")
|
arg(:group, :string, description: "Filter by group federated username")
|
||||||
|
arg(:group_id, :id, description: "Filter by group ID")
|
||||||
|
|
||||||
arg(:page, :integer,
|
arg(:page, :integer,
|
||||||
default_value: 1,
|
default_value: 1,
|
||||||
|
@ -461,6 +461,7 @@ defmodule Mobilizon.Actors do
|
|||||||
) do
|
) do
|
||||||
term
|
term
|
||||||
|> build_actors_by_username_or_name_page_query(options)
|
|> build_actors_by_username_or_name_page_query(options)
|
||||||
|
|> maybe_exclude_stale_actors(Keyword.get(options, :exclude_stale_actors, false))
|
||||||
|> maybe_exclude_my_groups(
|
|> maybe_exclude_my_groups(
|
||||||
Keyword.get(options, :exclude_my_groups, false),
|
Keyword.get(options, :exclude_my_groups, false),
|
||||||
Keyword.get(options, :current_actor_id)
|
Keyword.get(options, :current_actor_id)
|
||||||
@ -477,6 +478,17 @@ defmodule Mobilizon.Actors do
|
|||||||
|
|
||||||
defp maybe_exclude_my_groups(query, _, _), do: query
|
defp maybe_exclude_my_groups(query, _, _), do: query
|
||||||
|
|
||||||
|
@spec maybe_exclude_stale_actors(Ecto.Queryable.t(), boolean()) :: Ecto.Query.t()
|
||||||
|
defp maybe_exclude_stale_actors(query, true) do
|
||||||
|
actor_stale_period =
|
||||||
|
Application.get_env(:mobilizon, :activitypub)[:stale_actor_search_exclusion_after]
|
||||||
|
|
||||||
|
stale_date = DateTime.utc_now() |> DateTime.add(-actor_stale_period)
|
||||||
|
where(query, [a], is_nil(a.domain) or a.last_refreshed_at >= ^stale_date)
|
||||||
|
end
|
||||||
|
|
||||||
|
defp maybe_exclude_stale_actors(query, false), do: query
|
||||||
|
|
||||||
@spec build_actors_by_username_or_name_page_query(
|
@spec build_actors_by_username_or_name_page_query(
|
||||||
String.t(),
|
String.t(),
|
||||||
Keyword.t()
|
Keyword.t()
|
||||||
|
@ -53,7 +53,8 @@ defmodule Mobilizon.GraphQL.API.SearchTest do
|
|||||||
location: nil,
|
location: nil,
|
||||||
minimum_visibility: :public,
|
minimum_visibility: :public,
|
||||||
current_actor_id: nil,
|
current_actor_id: nil,
|
||||||
exclude_my_groups: false
|
exclude_my_groups: false,
|
||||||
|
exclude_stale_actors: true
|
||||||
],
|
],
|
||||||
1,
|
1,
|
||||||
10
|
10
|
||||||
|
Loading…
Reference in New Issue
Block a user