follows_resolver.ex 5.2 KB
Newer Older
James Laver's avatar
James Laver committed
1
# MoodleNet: Connecting and empowering educators worldwide
James Laver's avatar
James Laver committed
2
# Copyright © 2018-2020 Moodle Pty Ltd <https://moodle.com/moodlenet/>
James Laver's avatar
James Laver committed
3 4 5
# SPDX-License-Identifier: AGPL-3.0-only
defmodule MoodleNetWeb.GraphQL.FollowsResolver do

James Laver's avatar
James Laver committed
6
  alias MoodleNet.{Follows, GraphQL, Repo}
James Laver's avatar
James Laver committed
7 8 9 10 11 12 13
  alias MoodleNet.Follows.{
    Follow,
    FollowCount,
    FollowCountsQueries,
    FollowerCount,
    FollowerCountsQueries,
  }
James Laver's avatar
James Laver committed
14
  alias MoodleNet.GraphQL.{
James Laver's avatar
James Laver committed
15 16 17 18
    FetchFields,
    FetchPage,
    FetchPages,
    ResolveFields,
James Laver's avatar
James Laver committed
19 20
    ResolvePages,
  }
21
  alias MoodleNet.Meta.Pointers
James Laver's avatar
James Laver committed
22 23
  alias MoodleNet.Users.User

James Laver's avatar
James Laver committed
24 25
  def follow(%{follow_id: id}, info) do
    Follows.one(id: id, user: GraphQL.current_user(info))
James Laver's avatar
James Laver committed
26 27 28 29 30
  end

  def follow(parent, _, _info), do: {:ok, parent.follow}

  def my_follow_edge(%{id: id}, _, info) do
James Laver's avatar
James Laver committed
31
    with {:ok, %User{}} <- GraphQL.current_user_or(info, nil) do
James Laver's avatar
James Laver committed
32 33 34 35 36 37 38 39
      ResolveFields.run(
        %ResolveFields{
          module: __MODULE__,
          fetcher: :fetch_my_follow_edge,
          context: id,
          info: info,
        }
      )
James Laver's avatar
James Laver committed
40 41 42
    end
  end

James Laver's avatar
James Laver committed
43
  def fetch_my_follow_edge(info, ids) do
James Laver's avatar
James Laver committed
44 45 46 47
    fetch_my_follow_edge(GraphQL.current_user(info), info, ids)
  end

  def fetch_my_follow_edge(nil, _, _), do: nil
48 49 50 51 52 53 54 55 56
  def fetch_my_follow_edge(user, _info, ids) do
    FetchFields.run(
      %FetchFields{
        queries: Follows.Queries,
        query: Follow,
        group_fn: &(&1.context_id),
        filters: [deleted: false, creator: user.id, context: ids],
      }
    )
James Laver's avatar
James Laver committed
57
  end
James Laver's avatar
James Laver committed
58
  
James Laver's avatar
James Laver committed
59

James Laver's avatar
James Laver committed
60
  def follow_count_edge(%{id: id}, _, info) do
James Laver's avatar
James Laver committed
61 62 63 64 65 66 67 68 69
    ResolveFields.run(
      %ResolveFields{
        module: __MODULE__,
        fetcher: :fetch_follow_count_edge,
        context: id,
        info: info,
        default: 0,
      }
    )
James Laver's avatar
James Laver committed
70 71 72
  end

  def fetch_follow_count_edge(_, ids) do
James Laver's avatar
James Laver committed
73 74
    FetchFields.run(
      %FetchFields{
James Laver's avatar
James Laver committed
75 76 77 78
        queries: FollowCountsQueries,
        query: FollowCount,
        group_fn: &(&1.creator_id),
        map_fn: &(&1.count),
79
        filters: [creator: ids],
James Laver's avatar
James Laver committed
80 81 82 83
      }
    )
  end

James Laver's avatar
James Laver committed
84
  def follows_edge(%User{id: id}, %{}=page_opts, info) do
James Laver's avatar
James Laver committed
85 86 87 88 89 90 91 92 93 94 95
    ResolvePages.run(
      %ResolvePages{
        module: __MODULE__,
        fetcher: :fetch_follows_edge,
        context: id,
        page_opts: page_opts,
        info: info,
      }
    )
  end

96 97 98 99 100 101 102 103 104 105 106 107 108 109
  # def fetch_follows_edge({page_opts, info}, ids) do
  #   user = GraphQL.current_user(info)
  #   FetchPages.run(
  #     %FetchPages{
  #       queries: Follows.Queries,
  #       query: Follow,
  #       group_fn: &(&1.creator_id),
  #       page_opts: page_opts,
  #       base_filters: [creator: ids, user: user],
  #       data_filters: [page: [desc: [created: page_opts]]],
  #       count_filters: [group_count: :context_id],
  #     }
  #   )
  # end
James Laver's avatar
James Laver committed
110 111 112

  def fetch_follows_edge(page_opts, info, ids) do
    user = GraphQL.current_user(info)
James Laver's avatar
James Laver committed
113 114
    FetchPage.run(
      %FetchPage{
James Laver's avatar
James Laver committed
115 116 117
        queries: Follows.Queries,
        query: Follow,
        page_opts: page_opts,
118
        base_filters: [creator: ids, user: user],
James Laver's avatar
James Laver committed
119 120 121 122 123
        data_filters: [page: [desc: [created: page_opts]]],
      }
    )
  end

124
  def follower_count_edge(%{follower_count: c}, _, _info) when is_integer(c), do: {:ok, c}
James Laver's avatar
James Laver committed
125

James Laver's avatar
tests  
James Laver committed
126
  def follower_count_edge(%{id: id}, _, info) do
James Laver's avatar
James Laver committed
127 128 129 130 131 132 133 134 135
    ResolveFields.run(
      %ResolveFields{
        module: __MODULE__,
        fetcher: :fetch_follower_count_edge,
        context: id,
        info: info,
        default: 0,
      }
    )
James Laver's avatar
James Laver committed
136 137
  end

James Laver's avatar
tests  
James Laver committed
138
  def fetch_follower_count_edge(_, ids) do
James Laver's avatar
James Laver committed
139 140
    FetchFields.run(
      %FetchFields{
James Laver's avatar
tests  
James Laver committed
141 142 143 144
        queries: FollowerCountsQueries,
        query: FollowerCount,
        group_fn: &(&1.context_id),
        map_fn: &(&1.count),
145
        filters: [context: ids],
James Laver's avatar
tests  
James Laver committed
146 147
      }
    )
James Laver's avatar
James Laver committed
148 149
  end

James Laver's avatar
James Laver committed
150
  def followers_edge(%{id: id}, %{}=page_opts, info) do
James Laver's avatar
James Laver committed
151 152 153 154 155 156 157 158 159
    ResolvePages.run(
      %ResolvePages{
        module: __MODULE__,
        fetcher: :fetch_followers_edge,
        context: id,
        page_opts: page_opts,
        info: info,
      }
    )
160 161
  end

162 163 164 165 166 167 168 169 170 171 172 173 174 175
  # def fetch_followers_edge({page_opts, info}, ids) do
  #   user = GraphQL.current_user(info)
  #   FetchPages.run(
  #     %FetchPages{
  #       queries: Follows.Queries,
  #       query: Follow,
  #       group_fn: &(&1.context_id),
  #       page_opts: page_opts,
  #       base_filters: [context: ids, user: user],
  #       data_filters: [page: [desc: [created: page_opts]]],
  #       count_filters: [group_count: :context_id],
  #     }
  #   )
  # end
James Laver's avatar
James Laver committed
176

James Laver's avatar
James Laver committed
177 178
  def fetch_followers_edge(page_opts, info, ids) do
    user = GraphQL.current_user(info)
James Laver's avatar
James Laver committed
179 180
    FetchPage.run(
      %FetchPage{
James Laver's avatar
tests  
James Laver committed
181 182 183
        queries: Follows.Queries,
        query: Follow,
        page_opts: page_opts,
184
        base_filters: [context: ids, user: user],
James Laver's avatar
James Laver committed
185
        data_filters: [page: [desc: [created: page_opts]]],
James Laver's avatar
tests  
James Laver committed
186
      }
James Laver's avatar
James Laver committed
187 188 189 190 191
    )
  end

  def create_follow(%{context_id: id}, info) do
    Repo.transact_with fn ->
James Laver's avatar
James Laver committed
192
      with {:ok, me} <- GraphQL.current_user_or_not_logged_in(info),
James Laver's avatar
James Laver committed
193 194 195 196 197 198
           {:ok, pointer} <- Pointers.one(id: id) do
        Follows.create(me, pointer, %{is_local: true})
      end
    end
  end

Karen Konou's avatar
Karen Konou committed
199
  def follow_remote_actor(%{url: url}, info) do
James Laver's avatar
James Laver committed
200 201
    Repo.transact_with fn ->
      with {:ok, me} <- GraphQL.current_user_or_not_logged_in(info),
Karen Konou's avatar
Karen Konou committed
202
           {:ok, actor} <- MoodleNet.ActivityPub.Adapter.get_actor_by_ap_id(url) do
James Laver's avatar
James Laver committed
203 204
        Follows.create(me, actor, %{is_local: true})
      end
Karen Konou's avatar
Karen Konou committed
205 206
    end
  end
James Laver's avatar
James Laver committed
207
end