This tutorial explains how to get your application to insert itself into the various default menus. Start by creating a standard module with the name Tutorial05
. Before we provide that code that will let this application insert itself in system menus, we want to talk a bit about the design challenges of getting multiple modules to interact.
It is common for applications to want to use components that have been created by other applications. RedSquare and the Arcade both let the Chat module render itself into their sidebars, for instance, while third party crypto modules can add themselves to the Saito Wallet. Similarly, if RedSquare is installed the in-game menu will let players tweet a screenshot of their game.
Programmers who are new to Saito often try to achieve this sort of cross-module interactivity b hardcoding connections between applications. This can be done by iterating through all of the modules that exist on the app.modules.mods
object until you find the module you want and manually calling the functions in that module.
let chatmod = app.modules.returnModuleByName("Chat");
if (chatmod) {
// do something!
}
The problem with this approach is that it requires hardcoding a dependency between modules, so that if a user does not have both modules installed, or wants to upgrade either of their modules they now need to manage the dependencies between those modules.
We solve this with a design pattern called the respondTo()
approach. In this approach, modules can ask Saito to provide them with a list of modules that respondTo()
specific requests. The objects returned by those modules contain a specific mix of variables and functions that can be queried for data, or rendered directly to the screen.
To see how this works in practice, let's modify our Tutorial05 application so that it responds to* the standard menu components the Saito makes available and allows users to interact or load it through standard navigation components.
This design pattern is used by the UI Components that display menus throughout the site. You can learn more about all of the triggers to which modules can respondTo()
, but if you are getting started here are the three major triggers to which modules can respond that will insert options into the Saito UI:
respondTo(type = '', obj) {
let this_mod = this;
if (type === 'user-menu') {
return [{
text: `Tutorial05 User Menu`,
icon: 'fa-solid fa-5',
callback: function (app, publicKey) {
if (app.BROWSER) { alert("Clicked!"); }
}
}];
}
if (type === 'saito-header') {
return [
{
text: 'Tutorial05',
icon: 'fa-solid fa-5',
rank: 10,
callback: function (app, id) {
if (app.BROWSER) { alert("Tutorial05 Header Menu"); }
},
}
];
}
if (type == 'saito-floating-menu') {
return [
{
text: 'Tutorial05',
icon: 'fa-solid fa-5',
callback: function (app, id) {
if (app.BROWSER) { alert("Tutorial05 Header Menu"); }
},
}
]
}
return null;
}
Add this function to your application and compile it, and you'll be able to see that your module is now part of the three major menus: the main-menu that appears when you click on the hamburger menu, the user menu that appears if you click on a user's publickey or username, and the floating menu that appears on mobile devices. You can see if by visiting RedSquare on your phone and clicking on the "add tweet" button that will appear on the bottom-right of your screen.
Because the respondTo
function returns an object or an array of objects, it provides an extremely flexible way to define behavior. UI Components will typically respondTo
other components and expose their render()
function.
tutorial05
code can be referenced here.