Monarch API

Llordzeel1/27/2022
Alright, adventurous ones: I have a Beta version of Monarch with the new components API!

Manifest: https://github.com/zeel01/monarch/releases/download/v0.3.6/module.json

API Docs: https://github.com/zeel01/monarch/blob/dynamic-components/readme.md#-monarch-api

This API allows you to respond to a hook, and manipulate a set of data that describes info badges and controls that will display on the cards in each app. You can remove items (hide suit, value, and type?), add badges and controls, or even re-arrange stuff if you like.

Controls are similar to header buttons. They each get a class to name them, and an onclick method which will be called when the user clicks. This callback will be passed the Card that the user was interacting with, along with the Cards container it's held within. By this method, you can replicate all the card interactions that core uses, or create just about anything you can come up with.

I used this system to implement a "discard" button which can be tested by pasting the id of a pile into the setting under module settings. I'll probably change this later to be a drop down menu or something.

@Matt @FloRadical @Norc @Lucas Ferreira @BadIdeasBureau

Any feedback on the system/documentation would be super appreciated. I think I have a pretty robust implementation, but no plan survives contact with the enemy 😉
UUUnknown User1/27/2022
2 Messages Not Public
Sign In & Join Server To View
Bbadideasbureau1/27/2022
Shiny!
Bbadideasbureau1/27/2022
Looking at the docs (will poke the actual module ~this weekend), it looks like the badges only display for the currently selected card, is that right? Being able to show a badge on all cards that fit a given criterion would be handy for Torg (to show all cards in pool at a glance)
Llordzeel1/27/2022
A badge will show on all cards, unless hide is set to true for one of them.

Of course, since the card HUD isn't visible for cards you aren't hovering you won't see more than one at a time in the hand.

Markers of some form are a future addition though, and will likely have some means of seeing which cards are marked all the time.
Llordzeel1/27/2022
The function you pass as text will be called for each card.
Llordzeel1/27/2022
All the badges/controls on the cards use the new system now. So if you load up thr module you will see what I mean.
Bbadideasbureau1/27/2022
Makes sense, thanks
Llordzeel1/28/2022
Ah, I love it when you spend a day annoyed by something you did but can't for some reason come up with a better idea. Then the next day you immediately realize a better choice.

I was bothered that I named the hook getMonarchHandCommands since it's commands and other stuff, but didn't want to make it multiple hooks. Then I looked at the title I gave my release: "Components API Beta"

...Components :facepalmpicard:

So... breaking API change incoming (lmao): I'll be changing the name of the hook in the next pre-release. I'm pretty sure nobody wrote any code yet though, so 😆
Llordzeel1/28/2022
So will be getMonarchHandComponents, getMonarchDeckComponents, etc.
Llordzeel1/28/2022
Hmm....

Query: Should I change the hook signature to pass all the component arrays in a "components" object, so that they can be referenced by name?

components = {
  controls: Array<CardControl>,
  badges: Array<CardBadge>,
  markers: Array<CardMarker>,
  ...
}

Then the order of the parameters won't matter, you would just do:

Hooks.on("getMonarchHandComponents", (monarch, components) => {
  components.badges.push({
    ...
  });
});

Thoughts?
Llordzeel1/28/2022
This would make it more robust against changes in the API later, as adding to this object would not cause the hook signature to change.
Bbadideasbureau1/28/2022
I like that approach
Llordzeel1/28/2022
Okay, I made those changes and updated the links above:

https://github.com/zeel01/monarch/releases/download/v0.3.1/module.json
Llordzeel1/28/2022
@BadIdeasBureau Markers!
Bbadideasbureau1/28/2022
Yessss!
UUUnknown User1/29/2022
4 Messages Not Public
Sign In & Join Server To View
Llordzeel1/29/2022
There are JS Doc types 😜
UUUnknown User1/29/2022
2 Messages Not Public
Sign In & Join Server To View
Llordzeel1/29/2022
Is there a way for me to define the types without using TS?
Llordzeel1/29/2022
I'm not opposed to maintaining a type definition, but I don't want to actually write my code in TS.
UUUnknown User1/29/2022
2 Messages Not Public
Sign In & Join Server To View
Llordzeel1/29/2022
I'll look into it
Llordzeel1/29/2022
Do you mind opening a Github issue so I can't forget?
UUUnknown User1/29/2022
2 Messages Not Public
Sign In & Join Server To View
Llordzeel1/29/2022
Hooks man. So cool. But freaking impossible to properly define. JS Doc doesn't handle it right, I'm betting TS is all 🤷 about it too.
UUUnknown User1/29/2022
Message Not Public
Sign In & Join Server To View
Llordzeel1/31/2022
@FloRadical As a test, I tried just having it generate .d.ts from the JS docs, and set my release workflow to attach that file to my releases. If you get a chance to check it, is the difinition attached to this sufficient?

https://github.com/zeel01/monarch/releases/tag/v0.3.2.t
UUUnknown User1/31/2022
Message Not Public
Sign In & Join Server To View
Llordzeel1/31/2022
Deep magic
UUUnknown User1/31/2022
Message Not Public
Sign In & Join Server To View
Llordzeel1/31/2022
So that my apps that don't share the same base can share functionality.
UUUnknown User1/31/2022
Message Not Public
Sign In & Join Server To View
Llordzeel1/31/2022
It's possible that I did one of thise "TS can not fathom this JS" things.
UUUnknown User1/31/2022
Message Not Public
Sign In & Join Server To View
Llordzeel1/31/2022
Mixins don't break polymorphism! (much)
Llordzeel1/31/2022
It's not my fault this language doesn't support multiple inheritance.
UUUnknown User1/31/2022
Message Not Public
Sign In & Join Server To View
Llordzeel1/31/2022
Honestly the only things that you need types for are the typedefs in Components.js
Llordzeel1/31/2022
And the hook
Llordzeel1/31/2022
Which is still 🤷 to me
UUUnknown User1/31/2022
Message Not Public
Sign In & Join Server To View
Llordzeel1/31/2022
And they aren't even full classes, just objects of stuff
UUUnknown User1/31/2022
Message Not Public
Sign In & Join Server To View
Llordzeel1/31/2022
I maybe should type the callback functions though
Llordzeel1/31/2022
Actually, how does one do that.
UUUnknown User1/31/2022
3 Messages Not Public
Sign In & Join Server To View
Llordzeel1/31/2022
Well I would like for system devs using TS not to be angry with using it
Llordzeel1/31/2022
Like:
/**
* @typedef  {Object} CardControl                   An object defining a control to display on a card.
 * @property {string|Function<string>}   [tooltip]  - The tooltip of the control, or a function that returns the tooltip
 * @property {string|Function<string>}   [aria]     - The aria label (for screen readers) of the control, or a function that returns the aria label
 * @property {string|Function<string>}   [icon]     - The icon to display for the control, or a function that returns the icon
 * @property {string}                    [class]    - The css class to apply to the control
 * @property {boolean|Function<boolean>} [disabled] - Whether the control is disabled, or a function that returns whether the control is disabled
 * @property {Function}                  [onclick]  - The function to call when the control is clicked
 * @property {Array<CardControl>}        [controls] - An array of controls to display as a group
*/

How do I type hint the parameters that get passed to onclick or to tooltip?
Llordzeel1/31/2022
I know how to do Function<boolean> to hint the return value
UUUnknown User1/31/2022
3 Messages Not Public
Sign In & Join Server To View
Llordzeel1/31/2022
event, card, and container
UUUnknown User1/31/2022
Message Not Public
Sign In & Join Server To View
Llordzeel1/31/2022
/**
 * @callback clickCallback
 * @param {Event} event
 * @param {Card} card
 * @param {Cards} container
 * @returns {string}
 */
Llordzeel1/31/2022
This seems to perhaps do the trick?
Llordzeel1/31/2022
export type clickCallback = (event: Event, card: Card, container: Cards) => string;
UUUnknown User1/31/2022
2 Messages Not Public
Sign In & Join Server To View
Llordzeel1/31/2022
Then if I use clickCallback as the type instead of Function it seems right?
UUUnknown User1/31/2022
2 Messages Not Public
Sign In & Join Server To View
Llordzeel1/31/2022
Okay, so now how does the hook get handled?
Llordzeel1/31/2022
I have a Components typedef. So the signature for the Hook callback is:
(monarch: FormApplication, components: Components) => void
UUUnknown User1/31/2022
Message Not Public
Sign In & Join Server To View
Llordzeel1/31/2022
components.contextMenu is an array of CardControl, so not much different from components.controls just displayed inside this nifty context menu. By default, I've added toggles for the seven colored markers I included in v0.3.2
UUUnknown User1/31/2022
Message Not Public
Sign In & Join Server To View
Llordzeel1/31/2022
Possibly
Llordzeel1/31/2022
Additional built in buttons/settings will be added when the API is done.
UUUnknown User1/31/2022
2 Messages Not Public
Sign In & Join Server To View
Llordzeel1/31/2022
You can make it disabled too
Llordzeel1/31/2022
So the button is there, but can't be used.
Llordzeel1/31/2022
And you can disable it per-card.
Llordzeel1/31/2022
So if they have the mana for one card, but not another, you can control that.
Llordzeel1/31/2022
And you can always look through the controls array for the play button, and give it a disable function.
Llordzeel1/31/2022
Rather than replacing/removing the button.
UUUnknown User1/31/2022
Message Not Public
Sign In & Join Server To View
Llordzeel1/31/2022
Yep
Llordzeel2/2/2022
Wooo! Finally: AppControls

These componenets are used to add the buttons on the sheet for manipulating the whole application or pile.

https://github.com/zeel01/monarch/releases/download/v0.3.4/module.json

Found in components.appControls these work very similarly to card controls, but the callback signatures are a little different since they don't reference specific cards. This array is empty/ignored for the Card sheet, for it use controls and a CardControl since those are designed to reference a Card object.
Llordzeel2/2/2022
And that I believe is the end of the Dynamic Components portion of the API!

I have a few more API things I want to add before I release this is a public build, plus some non-API issues to deal with. I would greatly appreciate any API feedback I can get before then though.
UUUnknown User2/4/2022
Message Not Public
Sign In & Join Server To View