Mes coses

This commit is contained in:
BinarySandia04 2024-10-06 01:36:18 +02:00
parent 73a3432c57
commit d5856416fa
15 changed files with 278 additions and 80 deletions

View File

@ -84,7 +84,7 @@ class BackendRouter {
/**
* @hideconstructor
*/
class Model {
class BackendModel {
#_name;
#_plugin;
#_schema;

View File

@ -1,5 +1,4 @@
#!/bin/bash
# Gen docs
npm run generate-docs

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

View File

@ -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"
}

View File

@ -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));
}
}

View File

@ -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,
}

View File

@ -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");

View File

@ -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');
}

View File

@ -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>

View File

@ -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 };

View File

@ -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
View 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
View 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

View File

@ -1 +0,0 @@
This guide will help you through creating a plugin for Dragonroll

View File

@ -1,5 +1,8 @@
{
"plugin": {
"title": "Creating a plugin"
"firstplugin": {
"title": "Creating your first plugin"
},
"howtoread": {
"title": "How to read this documentation"
}
}