Revenue Cat Jetpack Compose Purchase Package - android-jetpack-compose

I'm trying to purchase a packages using the Revenue Cat SDK under JetPack Compose.
The SDK provides a function called PurchasePackage() (and PurchasePackageWith()) but all of these function's signatures require an Activity which I do not know how to obtain from an #Composable.
I've tried this answer from S.O. https://stackoverflow.com/a/68423182/695524 but that gives my null as the Activity.
What does work is: val activity = LocalContext.current as Activity but, according to this answer: https://stackoverflow.com/a/65243835/695524 that is potentially unsafe to user in production code.
So, how to safely obtain an Activity from Jetpack compose so I can Purchase a Package using the Revenue Cat SDK?

Thanks a lot Pylyp Dukov
Thanks to your comment, I've changed the solution to this answer: https://stackoverflow.com/a/68423182/695524 as folows:
fun Context.getActivity(): Activity? = when (this) {
is AppCompatActivity -> this
is ComponentActivity -> this
is Activity -> this
is ContextWrapper -> baseContext.getActivity()
else -> null
}
Now, from an #Composable function, I'm able to get the/an Activity like this:
val activity = LocalContext.current.getActivity()
And now I'm able to complete a purchase with Revenue Cat.

Related

F# interactive script load management

Suppose I have the following scripts:
C.fsx
namespace FruitSalad
type Cherry =
{
Cherry : int
}
B.fsx
#load "./C.fsx"
namespace FruitSalad
type Banana =
{
Banana : int
Cherry : Cherry
}
A.fsx
#load "B.fsx"
#load "C.fsx"
open FruitSalad
type Apple =
{
Apple : int
Banana : Banana
Cherry : Cherry
}
let c =
{
Cherry = 3
}
let a =
{
Apple = 1
Banana =
{
Banana = 2
Cherry = c
}
Cherry = c
}
printfn "%A" a
Running A.fsx gives this error:
error FS0001: This expression was expected to have type
'FSI_0001.FruitSalad.Cherry'
but here has type
'FSI_0002.FruitSalad.Cherry'
I can fix this by removing #load "C.fsx" from A.fsx.
However, maintaining this is awkward for much larger script projects.
Does F# support something like "include once" so that this is not necessary?
I agree with the comment by Fyodor that having a project might be easier. Note that you can create a project with a number of *.fs files in it, but still also have a *.fsx file that loads all the files from the project. This way, the IDE will read information from the project (and all your autocomplete will work), but you will also be able to run everything from a script file, which just needs to #load all the *.fs files in the correct order.
Another option that might help you if you prefer to stick to scripts is to use #load with multiple files at the same time. In the case above, you should be able to do:
#load "./B.fsx" "./C.fsx"
This way, F# interactive will know that you are loading these two files at the same time and will not create a separate version of C.fsx while loading B.fsx.

How to find where a process started in elixir

I am using observer in elixir and the following is the snapshot of an Application [under applications tab]:
I need to exit these processes once their work is done. Somehow, I am not able to figure out where some of the processes are originating. Is there a way in elixir/erlang to figure out the module/function where a particular process was created?
Suggestions will be highly appreciated. Thanks.
First you must always have the process's PID or its reference name.
Process.info/2
will give you information about that Process. You may get more documentation and information on how this function works in the Erlang's function it is calling:
process_info-2
There are also arity 1 variants: Process Docs
[erlang:process_info(Pid, initial_call) || Pid <- erlang:processes()].
But note that gen_server, etc., all have the same initial call, so you need to dig a little deeper.
The following is adapted from https://gist.github.com/rlipscombe/a8e87583d47799170f8b:
lists:map(
fun(Pid) ->
InitialCall = case erlang:process_info(Pid, initial_call) of
{initial_call,{proc_lib,init_p,A}} ->
case erlang:process_info(Pid, dictionary) of
{dictionary, D} ->
proplists:get_value('$initial_call', D, undefined);
_ ->
{proc_lib,init_p,A}
end;
{initial_call,{erlang,apply,A}} ->
case erlang:process_info(Pid, current_function) of
{current_function,MFA} -> MFA;
_ -> {erlang,apply,A}
end;
{initial_call,IC} ->
IC;
Other ->
Other
end,
{Pid, InitialCall}
end, erlang:processes()).
Using process_info/1 you can get a list of process information from which initial_call and current_function could help you to find the initial function call with which the process was spawned and the current function call of the process respectively.
Also process_info(Pid, initial_call) and process_info(Pid, current_function) functions are using as shortcut.

How to call a unique registered gen_server process?

I'm new to Erlang and I'm trying to build a simple game server (learning purpose).
I have one client controller (supervisor) that creates multiple client handlers (gen_server). I have also one game controller (supervisor) that creates multiple game handlers (gen_server).
One game handler (game table) will then communicate with several client handlers (players). I create the client handlers like this:
client_handler.erl:
start_link(ClientId, UniqueId) ->
ClientHandlerId = utils:create_id(?MODULE, UniqueId), //client_handler_0
State = #state{client_id = ClientId, client_handler_id = ClientHandlerId},
gen_server:start_link({global, ClientHandlerId}, ?MODULE, State, []).
game_handler.erl:
start_link(ClientHandlerId, GameId, UniqueId) ->
GameHandlerId = utils:create_id(?MODULE, UniqueId), //game_handler_0
State = #state{client_handler_id = ClientHandlerId, game_id = GameId, game_handler_id = GameHandlerId},
gen_server:start_link({global, GameHandlerId}, ?MODULE, State, []).
My problem is that I want to talk between client_handler and game_handler without neither of them knowing about their inner structure. For now I use:
client_handler.erl:
gen_server:cast(game_handler_0, {make_move, MoveData}).
and this works great. However, I would like to use:
client_handler.erl:
game_handler_0:make_move(MoveData)
So I can build separate API:s for each module (only use -export functions). Is this possible?
Best regards,
xqtr
EDIT: typo
Yes, it is considered good practice to abstract away implementation details in that way. Just move the cast call into a function in game_handler.erl, something like:
make_move(UniqueId, MoveData) ->
GameHandlerId = utils:create_id(?MODULE, UniqueId),
gen_server:cast(GameHandlerId, {make_move, MoveData}).
and export make_move/2. (Or perhaps forget about UniqueId, and pass GameHandlerId directly to the make_move function.)

How to capturing auxcodes using jtapi for avaya phones?

I am implementing on CTI application which will monitor all events of agent. Currently I am having trouble in getting auxcodes events. By check the agent state i get the auxcodes but i want an event for auxcode changes so that immediately i can get the auxcodes.
You may extract an Avaya extension of Agent from the AgentEvent and the get the AgentStateInfo from it.
Agent agent = agentTerminalEvent.getAgent();
LucentV5AgentStateInfo lasi = (LucentV5AgentStateInfo)((LucentAgent)agent).getStateInfo();
int state = lasi.state;
int rc = lasi.reasonCode;
int wm = lasi.workMode;
(if this is what you are looking for)
EDIT :
It seems that you can monitor full agent activty by monitoring the ACDAddress with ACDAddressListener.
ae-services-jtapi-programmers-guide-6_3_1.pdf Appendix A Page 60 :
To completely monitor agent activity, please use an
ACDAddressListener
OLD (may be outdated):
BUT : Other AgentTerminalEvents or ACDAddressEvents then Logon and Logoff are not produced if the change of the agent's state is not done
by the JTAPI itself.
That means if an agent changes his state to NOT_READY using his phone
you will not receive an AgentTerminalEvent.
If that state change is done by your program (Agent.setState...) then
you will receive an event.

Unable to use Erlang/ets in receive block

I am trying to use Erlang/ets to store/update various informations by pattern matching received data. Here is the code
start() ->
S = ets:new(test,[]),
register(proc,spawn(fun() -> receive_data(S) end)).
receive_data(S) ->
receive
{see,A} -> ets:insert(S,{cycle,A}) ;
[[f,c],Fcd,Fca,_,_] -> ets:insert(S,{flag_c,Fcd,Fca});
[[b],Bd,Ba,_,_] -> ets:insert(S,{ball,Bd,Ba})
end,
receive_data(S).
Here A is cycle number, [f,c] is center flag , [b] is ball and Fcd,Fca, Bd, Ba are directions and angle of flag and ball from player.
Sender process is sending these informations. Here, pattern matching is working correctly which I checked by printing values of A, Fcd,Fca..etc. I believe there is something wrong with the use of Erlang/ets.
When I run this code I get error like this
Error in process <0.48.0> with exit value: {badarg,[{ets,insert,[16400,{cycle,7}]},{single,receive_data,1}]
Can anybody tell me what's wrong with this code and how to correct this problem?
The problem is that the owner of the ets-table is the process running the start/1 function and the default behavior for ets is to only allow the owner to write and other processes to read, aka protected. Two solutions:
Create the ets table as public
S = ets:new(test,[public]).
Set the owner to your newly created process
Pid = spawn(fun() -> receive_data(S) end,
ets:give_away(test, Pid, gift)
register(proc,Pid)
Documentation for give_away/3

Resources