diff options
Diffstat (limited to 'shard/lib/app')
-rw-r--r-- | shard/lib/app/chat.ex | 77 | ||||
-rw-r--r-- | shard/lib/app/identity.ex | 45 | ||||
-rw-r--r-- | shard/lib/app/pagestore.ex | 2 |
3 files changed, 115 insertions, 9 deletions
diff --git a/shard/lib/app/chat.ex b/shard/lib/app/chat.ex index 8c55869..be3b848 100644 --- a/shard/lib/app/chat.ex +++ b/shard/lib/app/chat.ex @@ -31,6 +31,10 @@ defmodule SApp.Chat do # ========= defmodule Manifest do + @moduledoc""" + Manifest for a public chat room defined by its name. + """ + defstruct [:channel] end @@ -42,8 +46,17 @@ defmodule SApp.Chat do defmodule PrivChat.Manifest do + @moduledoc""" + Manifest for a private chat room defined by the list of participants. + + Do not instanciate this struct directly, use `new` to ensure a canonical representation. + """ + defstruct [:pk_list] + @doc""" + Ensures a canonical representation by sorting pks and removing duplicates. + """ def new(pk_list) do %__MODULE__{pk_list: pk_list |> Enum.sort |> Enum.uniq} end @@ -322,7 +335,7 @@ defmodule SApp.Chat do end end - def msg_cmp({pk1, msgbin1, _sign1}, {pk2, msgbin2, _sign2}) do + defp msg_cmp({pk1, msgbin1, _sign1}, {pk2, msgbin2, _sign2}) do {ts1, msg1} = SData.term_unbin msgbin1 {ts2, msg2} = SData.term_unbin msgbin2 cond do @@ -335,4 +348,66 @@ defmodule SApp.Chat do true -> :duplicate end end + + # ================ + # PUBLIC INTERFACE + # ================ + + @doc""" + Subscribe to notifications for this chat room. + + The process calling this function will start recieving messages of the form: + + {:chat_recv, manifest, {pk, msgbin, sign}} + + or + + {:chat_send, manifest, {pk, msgbin, sign}} + + msgbin can be used in the following way: + + {timestamp, message} = SData.term_unbin msgbin + """ + def subscribe(shard_pid) do + GenServer.cast(shard_pid, {:subscribe, self()}) + end + + @doc""" + Send a message to a chat room. + """ + def chat_send(shard_pid, pk, msg) do + GenServer.cast(shard_pid, {:chat_send, pk, msg}) + end + + @doc""" + Read the history of a chat room. + + The second argument is the last message to read. + If nil, will read the n last messages. + If not nill, will read the n last messages until the specified bound. + """ + def read_history(shard_pid, bound, n) do + GenServer.call(shard_pid, {:read_history, bound, n}) + end + + @doc""" + Return a shard's manifest from its pid. + """ + def get_manifest(shard_pid) do + GenServer.call(shard_pid, :manifest) + end + + @doc""" + Returns timestamp of last message if chat room has unread messages, nil otherwise. + """ + def has_unread?(shard_pid) do + GenServer.call(shard_pid, :has_unread) + end + + @doc""" + Mark all messages as read + """ + def mark_read(shard_pid) do + GenServer.cast(shard_pid, :mark_read) + end end diff --git a/shard/lib/app/identity.ex b/shard/lib/app/identity.ex index 95ffb92..42d1bf8 100644 --- a/shard/lib/app/identity.ex +++ b/shard/lib/app/identity.ex @@ -1,14 +1,29 @@ defmodule SApp.Identity do + @moduledoc""" + Shard application for keeping state associated with a user's identity. + + Current functionality: + + - nickname + - peer info: ip, port to connect to if we want a secure connection with this person + (used for private chat) + + Future functionnality: + + - friend list + - notifications & invites + """ + use GenServer require Logger defmodule Manifest do - defstruct [:pk] - end + @moduledoc""" + Manifest for a user identity shard, defined by the public key of the user. + """ - defmodule State do - defstruct [:info, :rev, :signed] + defstruct [:pk] end defimpl Shard.Manifest, for: Manifest do @@ -17,6 +32,10 @@ defmodule SApp.Identity do end end + defmodule State do + defstruct [:info, :rev, :signed] + end + def start_link(pk) do GenServer.start_link(__MODULE__, pk) end @@ -139,11 +158,23 @@ defmodule SApp.Identity do end @doc""" + Get the info dict of an identity shard. The pid of the shard must be given as an argument. + """ + def get_info(pid) do + GenServer.call(pid, :get_info) + end + + @doc""" + Set the info dict of an identity shard. + """ + def set_info(pid, new_info) do + GenServer.call(pid, {:set_info, new_info}) + end + + @doc""" Get a user's nickname from his pk """ def get_nick(pk) do - pid = find_proc pk - info = GenServer.call(pid, :get_info) - info.nick + get_info(find_proc pk).nick end end diff --git a/shard/lib/app/pagestore.ex b/shard/lib/app/pagestore.ex index 86b0726..8f6be59 100644 --- a/shard/lib/app/pagestore.ex +++ b/shard/lib/app/pagestore.ex @@ -251,7 +251,7 @@ defmodule SApp.PageStore do end def ask_random_peers(state, key) do - SNet.Group.broadcast(state.netgroup, {state.shard_id, state.path, {:get, key}}, 3) + SNet.Group.broadcast(state.netgroup, {state.shard_id, state.path, {:get, key}}, nmax: 3) end defimpl SData.PageStore do |