Mes coses
This commit is contained in:
parent
73a3432c57
commit
d5856416fa
@ -84,7 +84,7 @@ class BackendRouter {
|
||||
/**
|
||||
* @hideconstructor
|
||||
*/
|
||||
class Model {
|
||||
class BackendModel {
|
||||
#_name;
|
||||
#_plugin;
|
||||
#_schema;
|
||||
|
Binary file not shown.
Before Width: | Height: | Size: 82 KiB |
@ -1,12 +0,0 @@
|
||||
{
|
||||
"id": "dnd-5e",
|
||||
"title": "Dungeons & Dragons 5e",
|
||||
"description": "Dungeons & Dragons Fifth edition game system support",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Aran Roig"
|
||||
}
|
||||
],
|
||||
"version": "1.0.0",
|
||||
"color": "#e92026"
|
||||
}
|
@ -15,13 +15,41 @@ import Server from '@/services/Server';
|
||||
class ClientApi {
|
||||
#_plugin
|
||||
#_router
|
||||
#_windows
|
||||
|
||||
/**
|
||||
* @param {*} plugin
|
||||
*/
|
||||
constructor(plugin){
|
||||
this.#_plugin = plugin
|
||||
this.#_router = new ClientRouter()
|
||||
this.#_router = new ClientRouter(plugin.package)
|
||||
this.#_windows = new ClientWindows(plugin.package)
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* @param {string} path The path to the view relative to the client folder
|
||||
* @returns {ClientView} a new ClientView corresponding to the view
|
||||
*/
|
||||
createView(path){
|
||||
return new ClientView(path);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a new registered Module
|
||||
* @param {string} id The id of the new module
|
||||
* @returns {ClientModule}
|
||||
*/
|
||||
createModule(id){
|
||||
return new ClientModule(id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a ClientModule
|
||||
* @param {ClientModule} module The client module
|
||||
*/
|
||||
registerModule(module){
|
||||
_Modules.CreateModule(module);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -31,6 +59,107 @@ class ClientApi {
|
||||
get router(){
|
||||
return this.#_router;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the windows object
|
||||
* @type {ClientWindows}
|
||||
*/
|
||||
get windows(){
|
||||
return this.#_windows;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for managing Dragonroll windows
|
||||
* @hideconstructor
|
||||
*/
|
||||
class ClientWindows {
|
||||
#_plugin;
|
||||
|
||||
constructor(plugin){
|
||||
this.#_plugin = plugin;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a new window for the given view
|
||||
* @param {string} name
|
||||
* @param {ClientView} view
|
||||
*/
|
||||
registerWindow(name, view){
|
||||
_Windows.InjectWindow(`${this.#_plugin}/${name}`, this.#_plugin, view.path)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Class for managing client views
|
||||
* @hideconstructor
|
||||
*/
|
||||
class ClientView {
|
||||
|
||||
#_path;
|
||||
|
||||
constructor(path){
|
||||
this.#_path = path;
|
||||
}
|
||||
|
||||
/**
|
||||
* @type {string} The path of the view
|
||||
*/
|
||||
get path(){
|
||||
return this.#_path;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @hideconstructor
|
||||
*/
|
||||
class ClientModule {
|
||||
#_id;
|
||||
#_title;
|
||||
#_description;
|
||||
#_version;
|
||||
#_color;
|
||||
#_icon;
|
||||
|
||||
constructor(id){ this.#_id = id; }
|
||||
|
||||
/**
|
||||
* The title of the module
|
||||
* @type {string}
|
||||
*/
|
||||
set title(title) { this.#_title = title; }
|
||||
|
||||
/**
|
||||
* The description of the module
|
||||
* @type {string}
|
||||
*/
|
||||
set description(description){ this.#_description = description; }
|
||||
|
||||
/**
|
||||
* The version of the module
|
||||
* @type {string}
|
||||
*/
|
||||
set version(version){ this.#_version = version; }
|
||||
|
||||
/**
|
||||
* The accent color of the module. This will be displayed for example
|
||||
* in the background title inside the campaign preview
|
||||
* @type {string}
|
||||
*/
|
||||
set color(color){ this.#_color = color; }
|
||||
|
||||
/**
|
||||
* Sets the icon for the module. It must be placed inside the public folder of the plugin
|
||||
*/
|
||||
set icon(icon){ this.#_icon = icon; }
|
||||
|
||||
/**
|
||||
* Gets the module info in a json format
|
||||
* @returns {Object}
|
||||
*/
|
||||
get info(){
|
||||
return {id: this.#_id, title: this.#_title, description: this.#_description, version: this.#_version, color: this.#_color, icon: this.#_icon}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@ -65,59 +194,74 @@ class ClientRouter {
|
||||
* @param {routerCallback} callback
|
||||
*/
|
||||
get(route, callback){
|
||||
Server().get(`${path}/${route}`).then(response => callback(response)).catch(err => console.log(err));
|
||||
Server().get(`${path}/${route}`).then(callback).catch(err => console.log(err));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a post request to specified plugin route
|
||||
* @param {String} route
|
||||
*
|
||||
* @param {Object} data
|
||||
* @param {routerCallback} callback
|
||||
*/
|
||||
post(route){
|
||||
|
||||
post(route, data, callback){
|
||||
Server().post(`${path}/${route}`, data).then(callback).catch(err => console.log(err));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a put request to specified plugin route
|
||||
* @param {String} route
|
||||
*
|
||||
* @param {Object} data
|
||||
* @param {routerCallback} callback
|
||||
*/
|
||||
put(route){
|
||||
|
||||
put(route, data, callback){
|
||||
Server().put(`${path}/${route}`, data).then(callback).catch(err => console.log(err));
|
||||
}
|
||||
|
||||
/**
|
||||
* Sends a delete request to specified plugin route
|
||||
* @param {String} route
|
||||
*
|
||||
* @param {routerCallback} callback
|
||||
*/
|
||||
delete(route){
|
||||
|
||||
delete(route, callback){
|
||||
Server().delete(`${route}`).then(callback).catch(err => console.log(err));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Sends a get request to an specified route
|
||||
* @param {String} route
|
||||
* @param {routerCallback} callback
|
||||
*/
|
||||
baseGet(){
|
||||
|
||||
baseGet(route, callback){
|
||||
Server().get(`${route}`).then(callback).catch(err => console.log(err));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Sends a post request to specified route
|
||||
* @param {String} route
|
||||
* @param {Object} data
|
||||
* @param {routerCallback} callback
|
||||
*/
|
||||
basePost(){
|
||||
|
||||
basePost(route, data, callback){
|
||||
Server().post(`${route}`, data).then(callback).catch(err => console.log(err));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Sends a put request to specified route
|
||||
* @param {String} route
|
||||
* @param {Object} data
|
||||
* @param {routerCallback} callback
|
||||
*/
|
||||
baseUpdate(){
|
||||
|
||||
basePut(route, data, callback){
|
||||
Server().put(`${route}`, data).then(callback).catch(err => console.log(err));
|
||||
}
|
||||
|
||||
/**
|
||||
*
|
||||
* Sends a delete request to specified route
|
||||
* @param {String} route
|
||||
* @param {routerCallback} callback
|
||||
*/
|
||||
baseDelete(){
|
||||
|
||||
baseDelete(route, callback){
|
||||
Server().delete(`${route}`).then(callback).catch(err => console.log(err));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1,37 +1,33 @@
|
||||
let modulesToLoad = [
|
||||
"dnd-5e"
|
||||
]
|
||||
let modules = [];
|
||||
let modules = {};
|
||||
|
||||
function CreateModule(module){
|
||||
let moduleInfo = module.info;
|
||||
modules[moduleInfo.id] = moduleInfo;
|
||||
}
|
||||
|
||||
/*
|
||||
async function GetJson(url){
|
||||
let obj = await (await fetch(url)).json();
|
||||
return obj;
|
||||
}
|
||||
*/
|
||||
|
||||
/*
|
||||
async function ImportModule(moduleFolder) {
|
||||
let moduleInfo = await GetJson('/modules/' + moduleFolder + '/module.json');
|
||||
modules.push(moduleInfo);
|
||||
}
|
||||
*/
|
||||
|
||||
let GetModules = () => modules;
|
||||
let GetModulesToLoad = () => modulesToLoad;
|
||||
// let GetModulesToLoad = () => modulesToLoad;
|
||||
|
||||
function GetModule(id){
|
||||
let module = null;
|
||||
modules.forEach(mod => {
|
||||
if(mod.id == id) module = mod;
|
||||
})
|
||||
return module;
|
||||
}
|
||||
|
||||
function CreateModule(moduleInfo, registeredWindows){
|
||||
|
||||
return modules[id];
|
||||
}
|
||||
|
||||
export {
|
||||
ImportModule,
|
||||
CreateModule,
|
||||
GetModules,
|
||||
GetModule,
|
||||
GetModulesToLoad,
|
||||
}
|
@ -67,9 +67,9 @@ let windowMap = {
|
||||
plugin_window: PluginWindow
|
||||
};
|
||||
|
||||
async function InjectWindow(plugin, window_type, window_component){
|
||||
async function InjectWindow(window_type, plugin, window_component){
|
||||
let systemWidows = {};
|
||||
systemWidows[plugin + "/" + window_type] = (await import(`../../plugins/${plugin}/views/${window_component}.vue`)).default;
|
||||
systemWidows[window_type] = (await import(`../../plugins/${plugin}/views/${window_component}.vue`)).default;
|
||||
windowMap = {...windowMap, ...systemWidows};
|
||||
|
||||
console.log("Window injected");
|
||||
|
@ -10,7 +10,6 @@ import { CreateWindow } from '@/services/Windows'
|
||||
import { GetUser, HasAdmin, LoadUser } from '@/services/User.js'
|
||||
import { DisplayToast, SetEmitter } from '@/services/Dragonroll';
|
||||
import { FetchResources } from '@/services/Resources';
|
||||
import { ImportModule } from '@/services/Modules';
|
||||
import { FetchPlugins } from '@/services/Plugins';
|
||||
import useEmitter from '@/services/Emitter';
|
||||
const emitter = useEmitter();
|
||||
@ -65,8 +64,6 @@ async function start(){
|
||||
await FetchResources();
|
||||
await FetchPlugins();
|
||||
|
||||
await ImportModule('dnd-5e')
|
||||
|
||||
DisplayToast('aqua', 'All plugins loaded successfully');
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,5 @@
|
||||
<script setup>
|
||||
import { inject, onMounted, ref } from 'vue';
|
||||
import { GetEmitter } from '../../services/Dragonroll';
|
||||
import { onMounted, ref } from 'vue';
|
||||
|
||||
const props = defineProps(['data', 'click']);
|
||||
const data = props.data;
|
||||
@ -13,8 +12,9 @@ function Select(){
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
console.log(data);
|
||||
title.value = data.title;
|
||||
image.value.src = "modules/" + data.id + "/icon.png"
|
||||
image.value.src = `plugins/${data.id}/${data.icon}`;
|
||||
})
|
||||
|
||||
</script>
|
||||
|
@ -2,24 +2,20 @@
|
||||
// Entrypoint
|
||||
function Main(Api){
|
||||
console.log("Hello World!");
|
||||
console.log(Api);
|
||||
|
||||
Api.Modules.CreateModule({
|
||||
"id": "dnd-5e",
|
||||
"title": "Dungeons & Dragons 5e",
|
||||
"description": "Dungeons & Dragons Fifth edition game system support",
|
||||
"authors": [
|
||||
{
|
||||
"name": "Aran Roig"
|
||||
}
|
||||
],
|
||||
"version": "0.1",
|
||||
"color": "#e92026"
|
||||
});
|
||||
let dndModule = Api.createModule('dnd-5e');
|
||||
|
||||
Api.Windows.InjectWindow('dnd-5e', 'character_sheet', 'CharacterSheet');
|
||||
Api.Windows.InjectWindow('dnd-5e', 'item_sheet', 'ItemSheet');
|
||||
Api.Windows.InjectWindow('dnd-5e', 'create_item_prompt', 'CreateItemPrompt');
|
||||
dndModule.title = "Dungeons & Dragons 5e";
|
||||
dndModule.description = "Dungeons & Dragons Fifth edition game system support";
|
||||
dndModule.version = "0.1";
|
||||
dndModule.color = "#e92026";
|
||||
dndModule.icon = "icon.png"
|
||||
|
||||
Api.windows.registerWindow('character_sheet', Api.createView('CharacterSheet'));
|
||||
Api.windows.registerWindow('item_sheet', Api.createView('ItemSheet'));
|
||||
Api.windows.registerWindow('create_item_promptç', Api.createView('CreateItemPrompt'));
|
||||
|
||||
Api.registerModule(dndModule);
|
||||
}
|
||||
|
||||
export { Main };
|
@ -12,6 +12,10 @@ function updateLogoThemes(){
|
||||
}
|
||||
|
||||
document.addEventListener("DOMContentLoaded", (event) => {
|
||||
let darkLogos = document.getElementsByClassName('logo-splash-dark');
|
||||
let lightLogos = document.getElementsByClassName('logo-splash-light');
|
||||
for(let i = 0; i < darkLogos.length; i++) darkLogos[i].style.display = "none";
|
||||
for(let i = 0; i < lightLogos.length; i++) lightLogos[i].style.display = "none";
|
||||
|
||||
const attrObserver = new MutationObserver((mutations) => {
|
||||
mutations.forEach(mu => {
|
||||
|
69
tutorials/firstplugin.md
Normal file
69
tutorials/firstplugin.md
Normal file
@ -0,0 +1,69 @@
|
||||
This guide will help you through creating a plugin for Dragonroll
|
||||
|
||||
## Downloading the example plugin
|
||||
|
||||
The quickest way to start a plugin is starting from the example plugin template that you can find in [this]() repository. Every Dragonroll plugin has the following file structure:
|
||||
|
||||
```tree
|
||||
/your-plugin/
|
||||
├── plugin.json
|
||||
├── client
|
||||
│ └── main.js
|
||||
│ └── ...
|
||||
├── backend
|
||||
│ └── main.js
|
||||
│ └── ...
|
||||
├── locales
|
||||
│ └── en-US.json
|
||||
│ └── ...
|
||||
└── public
|
||||
└── icon.png
|
||||
└── ...
|
||||
```
|
||||
|
||||
- The `plugin.json` contains basic information about your plugin, and also the entrypoints that Dragonroll will use to load and initialize the plugin
|
||||
- The `client` folder contains all the code of your plugin that is relative to the client
|
||||
- The `backend` folder contains all the code that is relative to the server
|
||||
- The `locales` folder contains the translation files for your plugin
|
||||
- The `public` folder contains all the media that will be publicly available for your plugin client
|
||||
|
||||
## The plugin.json file
|
||||
|
||||
Your `plugin.json` file defines important information about your plugin, like its name, package, authors, entrypoints, and other information
|
||||
|
||||
**Important**: The `package` field must be identical to the name of the folder containing your entire plugin
|
||||
|
||||
> `plugin.json`
|
||||
> ```json
|
||||
> {
|
||||
> "package": "your-plugin",
|
||||
> "name": "My custom plugin",
|
||||
> "description": "This is my first custom plugin",
|
||||
> "authors": [
|
||||
> {
|
||||
> "name": "Aran Roig"
|
||||
> }
|
||||
> ],
|
||||
> "version": "1.0",
|
||||
> "client": {
|
||||
> "entrypoint": "main.js"
|
||||
> },
|
||||
> "backend": {
|
||||
> "entrypoint": "main.js"
|
||||
> }
|
||||
> }
|
||||
> ```
|
||||
|
||||
## Entrypoints
|
||||
|
||||
When Dragonroll registers a plugin, it calls the `Main` method of the file specified in the entrypoint field inside the `plugin.json`, so if you don't export a function with that name your plugin won't load. Dragonroll passes its entire API through the main method
|
||||
|
||||
> `client/main.js` and `backend/main.js`
|
||||
> ```js main.js
|
||||
> function Main(Api){
|
||||
> console.log("Hello World!");
|
||||
> }
|
||||
> export { Main };
|
||||
> ```
|
||||
|
||||
In the client entrypoint, the `Api` variable will be a `ClientApi` object. In the backend entrypoint, the `Api` will be instead a `BackendApi` object.
|
3
tutorials/howtoread.md
Normal file
3
tutorials/howtoread.md
Normal file
@ -0,0 +1,3 @@
|
||||
- The classes starting with the prefix `Client` are client specific
|
||||
- The classes starting with the prefix `Backend` are backend specific
|
||||
- All the other classes are accessible from both sides
|
@ -1 +0,0 @@
|
||||
This guide will help you through creating a plugin for Dragonroll
|
@ -1,5 +1,8 @@
|
||||
{
|
||||
"plugin": {
|
||||
"title": "Creating a plugin"
|
||||
"firstplugin": {
|
||||
"title": "Creating your first plugin"
|
||||
},
|
||||
"howtoread": {
|
||||
"title": "How to read this documentation"
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user