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 * @hideconstructor
*/ */
class Model { class BackendModel {
#_name; #_name;
#_plugin; #_plugin;
#_schema; #_schema;

View File

@ -1,5 +1,4 @@
#!/bin/bash #!/bin/bash
# Gen docs # Gen docs
npm run generate-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 { class ClientApi {
#_plugin #_plugin
#_router #_router
#_windows
/** /**
* @param {*} plugin * @param {*} plugin
*/ */
constructor(plugin){ constructor(plugin){
this.#_plugin = 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(){ get router(){
return this.#_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 * @param {routerCallback} callback
*/ */
get(route, 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 {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 {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 {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 = [ let modules = {};
"dnd-5e"
]
let modules = [];
function CreateModule(module){
let moduleInfo = module.info;
modules[moduleInfo.id] = moduleInfo;
}
/*
async function GetJson(url){ async function GetJson(url){
let obj = await (await fetch(url)).json(); let obj = await (await fetch(url)).json();
return obj; return obj;
} }
*/
/*
async function ImportModule(moduleFolder) { async function ImportModule(moduleFolder) {
let moduleInfo = await GetJson('/modules/' + moduleFolder + '/module.json'); let moduleInfo = await GetJson('/modules/' + moduleFolder + '/module.json');
modules.push(moduleInfo); modules.push(moduleInfo);
} }
*/
let GetModules = () => modules; let GetModules = () => modules;
let GetModulesToLoad = () => modulesToLoad; // let GetModulesToLoad = () => modulesToLoad;
function GetModule(id){ function GetModule(id){
let module = null; return modules[id];
modules.forEach(mod => {
if(mod.id == id) module = mod;
})
return module;
}
function CreateModule(moduleInfo, registeredWindows){
} }
export { export {
ImportModule,
CreateModule, CreateModule,
GetModules, GetModules,
GetModule, GetModule,
GetModulesToLoad,
} }

View File

@ -67,9 +67,9 @@ let windowMap = {
plugin_window: PluginWindow plugin_window: PluginWindow
}; };
async function InjectWindow(plugin, window_type, window_component){ async function InjectWindow(window_type, plugin, window_component){
let systemWidows = {}; 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}; windowMap = {...windowMap, ...systemWidows};
console.log("Window injected"); console.log("Window injected");

View File

@ -10,7 +10,6 @@ import { CreateWindow } from '@/services/Windows'
import { GetUser, HasAdmin, LoadUser } from '@/services/User.js' import { GetUser, HasAdmin, LoadUser } from '@/services/User.js'
import { DisplayToast, SetEmitter } from '@/services/Dragonroll'; import { DisplayToast, SetEmitter } from '@/services/Dragonroll';
import { FetchResources } from '@/services/Resources'; import { FetchResources } from '@/services/Resources';
import { ImportModule } from '@/services/Modules';
import { FetchPlugins } from '@/services/Plugins'; import { FetchPlugins } from '@/services/Plugins';
import useEmitter from '@/services/Emitter'; import useEmitter from '@/services/Emitter';
const emitter = useEmitter(); const emitter = useEmitter();
@ -65,8 +64,6 @@ async function start(){
await FetchResources(); await FetchResources();
await FetchPlugins(); await FetchPlugins();
await ImportModule('dnd-5e')
DisplayToast('aqua', 'All plugins loaded successfully'); DisplayToast('aqua', 'All plugins loaded successfully');
} }

View File

@ -1,6 +1,5 @@
<script setup> <script setup>
import { inject, onMounted, ref } from 'vue'; import { onMounted, ref } from 'vue';
import { GetEmitter } from '../../services/Dragonroll';
const props = defineProps(['data', 'click']); const props = defineProps(['data', 'click']);
const data = props.data; const data = props.data;
@ -13,8 +12,9 @@ function Select(){
} }
onMounted(() => { onMounted(() => {
console.log(data);
title.value = data.title; title.value = data.title;
image.value.src = "modules/" + data.id + "/icon.png" image.value.src = `plugins/${data.id}/${data.icon}`;
}) })
</script> </script>

View File

@ -2,24 +2,20 @@
// Entrypoint // Entrypoint
function Main(Api){ function Main(Api){
console.log("Hello World!"); console.log("Hello World!");
console.log(Api);
Api.Modules.CreateModule({ let dndModule = Api.createModule('dnd-5e');
"id": "dnd-5e",
"title": "Dungeons & Dragons 5e",
"description": "Dungeons & Dragons Fifth edition game system support",
"authors": [
{
"name": "Aran Roig"
}
],
"version": "0.1",
"color": "#e92026"
});
Api.Windows.InjectWindow('dnd-5e', 'character_sheet', 'CharacterSheet'); dndModule.title = "Dungeons & Dragons 5e";
Api.Windows.InjectWindow('dnd-5e', 'item_sheet', 'ItemSheet'); dndModule.description = "Dungeons & Dragons Fifth edition game system support";
Api.Windows.InjectWindow('dnd-5e', 'create_item_prompt', 'CreateItemPrompt'); 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 }; export { Main };

View File

@ -12,6 +12,10 @@ function updateLogoThemes(){
} }
document.addEventListener("DOMContentLoaded", (event) => { 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) => { const attrObserver = new MutationObserver((mutations) => {
mutations.forEach(mu => { 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": { "firstplugin": {
"title": "Creating a plugin" "title": "Creating your first plugin"
},
"howtoread": {
"title": "How to read this documentation"
} }
} }