Getting things ready for dnd
This commit is contained in:
parent
5875b69089
commit
168d683b13
BIN
client/public/modules/dnd-5e/icon.png
Normal file
BIN
client/public/modules/dnd-5e/icon.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 82 KiB |
12
client/public/modules/dnd-5e/module.json
Normal file
12
client/public/modules/dnd-5e/module.json
Normal file
@ -0,0 +1,12 @@
|
||||
{
|
||||
"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"
|
||||
}
|
@ -6,10 +6,43 @@ import { RouterLink, RouterView } from 'vue-router'
|
||||
import { GetUser, UserStatus, LoadUser } from '@/services/User.js'
|
||||
import { IsAdmin } from './services/User'
|
||||
|
||||
import useEmitter from '@/services/Emitter';
|
||||
const emitter = useEmitter();
|
||||
|
||||
import { DisplayToast, SetEmitter } from './services/Dragonroll'
|
||||
import { ImportModule, GetModulesToLoad } from './services/Modules'
|
||||
import { CreateWindow } from './services/Windows';
|
||||
|
||||
console.clear();
|
||||
console.log("%cLoaded!!!", "color: #22ff22; font-size: 24px");
|
||||
LoadUser();
|
||||
|
||||
SetEmitter(emitter);
|
||||
onMounted(() => {
|
||||
async function preloadModules(){
|
||||
const modules = GetModulesToLoad();
|
||||
let moduleLoads = [];
|
||||
|
||||
modules.forEach(moduleName => {
|
||||
moduleLoads.push(ImportModule(moduleName));
|
||||
});
|
||||
|
||||
await Promise.all(moduleLoads);
|
||||
DisplayToast('aqua', 'All modules loaded successfully');
|
||||
|
||||
if(GetUser()){
|
||||
CreateWindow('main_menu')
|
||||
// CreateWindow('test');
|
||||
DisplayToast('green', 'Logged in successfully as ' + GetUser().username + '!', 3000)
|
||||
return;
|
||||
}
|
||||
CreateWindow('login');
|
||||
}
|
||||
|
||||
preloadModules();
|
||||
})
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
|
@ -164,4 +164,4 @@ button:active {
|
||||
|
||||
.param-value {
|
||||
margin-left: auto;
|
||||
}
|
||||
}
|
||||
|
@ -27,14 +27,11 @@ import 'prismjs/components/prism-csharp';
|
||||
import 'prismjs/components/prism-ruby';
|
||||
import 'prismjs/components/prism-bash';
|
||||
|
||||
|
||||
VueMarkdownEditor.lang.use('es-Es', esEs);
|
||||
VueMarkdownEditor.use(vuepressTheme, { Prism });
|
||||
VueMarkdownEditor.use(createKatexPlugin());
|
||||
|
||||
const app = createApp(App).use(VueMarkdownEditor);
|
||||
|
||||
|
||||
app.config.globalProperties.emitter = emitter
|
||||
app.config.globalProperties.rollWindows = {
|
||||
login: reactive([]),
|
||||
@ -46,4 +43,5 @@ app.config.globalProperties.rollWindows = {
|
||||
|
||||
app.use(router)
|
||||
|
||||
app.mount('#app')
|
||||
app.mount('#app')
|
||||
|
||||
|
@ -5,6 +5,7 @@ import Api from '@/services/Api'
|
||||
import { backendUrl } from './BackendURL';
|
||||
import { GetUser } from './User';
|
||||
import { ExitGame } from './Game';
|
||||
import { GetModule } from './Modules';
|
||||
|
||||
let emitter;
|
||||
|
||||
@ -12,6 +13,8 @@ function SetEmitter(newEmitter){
|
||||
emitter = newEmitter
|
||||
}
|
||||
|
||||
let GetEmitter = () => emitter;
|
||||
|
||||
function DisplayToast(color, text, duration = 1000){
|
||||
emitter.emit("toast", {color, text, duration});
|
||||
}
|
||||
@ -109,8 +112,13 @@ function GetPlayer(player_campaign){
|
||||
if(index != -1) return players.value[index];
|
||||
}
|
||||
|
||||
function GetSystem(){
|
||||
if(currentCampaign) return GetModule(currentCampaign.system)
|
||||
}
|
||||
|
||||
export {
|
||||
SetEmitter,
|
||||
GetEmitter,
|
||||
|
||||
DisplayToast,
|
||||
|
||||
@ -122,6 +130,7 @@ export {
|
||||
GetClient,
|
||||
GetPlayerList,
|
||||
GetPlayer,
|
||||
GetSystem,
|
||||
|
||||
GetChatRef,
|
||||
SendMessage
|
||||
|
32
client/src/services/Modules.js
Normal file
32
client/src/services/Modules.js
Normal file
@ -0,0 +1,32 @@
|
||||
let modulesToLoad = [
|
||||
"dnd-5e"
|
||||
]
|
||||
let modules = [];
|
||||
|
||||
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;
|
||||
|
||||
function GetModule(id){
|
||||
let module = null;
|
||||
modules.forEach(mod => {
|
||||
if(mod.id == id) module = mod;
|
||||
})
|
||||
return module;
|
||||
}
|
||||
|
||||
export {
|
||||
ImportModule,
|
||||
GetModules,
|
||||
GetModule,
|
||||
GetModulesToLoad,
|
||||
}
|
@ -4,6 +4,11 @@ import { Disconnect } from './Dragonroll';
|
||||
const windows = ref([])
|
||||
|
||||
const defValues = {
|
||||
'test': {
|
||||
id: "example",
|
||||
title: "Example",
|
||||
close: true
|
||||
},
|
||||
'login': {
|
||||
id: 'login',
|
||||
title: 'Login',
|
||||
@ -74,6 +79,11 @@ const defValues = {
|
||||
id: 'environment',
|
||||
title: 'Edit environment',
|
||||
close: true
|
||||
},
|
||||
'system_selector': {
|
||||
id: 'system-selector',
|
||||
title: "Select a game system",
|
||||
close: true
|
||||
}
|
||||
}
|
||||
|
||||
@ -214,8 +224,8 @@ function ClearAll(){
|
||||
}
|
||||
|
||||
function ClearWindows(data){
|
||||
for (let i = 0; i < windows[data.type].value.length; i++) {
|
||||
ClearWindow(windows[data.type].value[i].id);
|
||||
for (let i = 0; i < windows.value.length; i++) {
|
||||
ClearWindow(windows.value[i].id);
|
||||
}
|
||||
// reload.value += 1;
|
||||
}
|
||||
|
@ -2,9 +2,6 @@
|
||||
import { onMounted } from 'vue';
|
||||
import { RouterLink, RouterView } from 'vue-router'
|
||||
|
||||
import useEmitter from '@/services/Emitter';
|
||||
const emitter = useEmitter();
|
||||
|
||||
import WindowManager from '@/views/managers/WindowManager.vue'
|
||||
import { GetUser } from '@/services/User'
|
||||
|
||||
@ -13,17 +10,6 @@ import Toast from './partials/Toast.vue';
|
||||
import { DisplayToast, SetEmitter } from '../services/Dragonroll';
|
||||
import GameManager from './managers/GameManager.vue';
|
||||
|
||||
onMounted(() => {
|
||||
SetEmitter(emitter);
|
||||
if(GetUser()){
|
||||
CreateWindow('main_menu')
|
||||
DisplayToast('green', 'Logged in successfully as ' + GetUser().username + '!', 3000)
|
||||
return;
|
||||
}
|
||||
CreateWindow('login');
|
||||
}
|
||||
);
|
||||
|
||||
|
||||
</script>
|
||||
|
||||
|
@ -19,12 +19,14 @@ import ChatWindow from '../windows/game/ChatWindow.vue'
|
||||
import DiceWindow from '../windows/game/DiceWindow.vue'
|
||||
import MapButtons from '../windows/dm/MapButtons.vue'
|
||||
import EnvironmentWindow from '../windows/dm/EnvironmentWindow.vue'
|
||||
import SystemSelectorWindow from '../windows/campaigns/SystemSelectorWindow.vue'
|
||||
|
||||
// Gestionem ventanas
|
||||
const reload = ReloadRef();
|
||||
const windows = Windows();
|
||||
|
||||
const WindowMap = {
|
||||
test: ExampleWindow,
|
||||
login: LoginWindow,
|
||||
main_menu: MainMenuWindow,
|
||||
register: RegisterWindow,
|
||||
@ -37,7 +39,8 @@ const WindowMap = {
|
||||
chat: ChatWindow,
|
||||
dice_menu: DiceWindow,
|
||||
map_buttons: MapButtons,
|
||||
environment: EnvironmentWindow
|
||||
environment: EnvironmentWindow,
|
||||
system_selector: SystemSelectorWindow
|
||||
};
|
||||
</script>
|
||||
|
||||
|
68
client/src/views/partials/GameSystem.vue
Normal file
68
client/src/views/partials/GameSystem.vue
Normal file
@ -0,0 +1,68 @@
|
||||
<script setup>
|
||||
import { inject, onMounted, ref } from 'vue';
|
||||
import { GetEmitter } from '../../services/Dragonroll';
|
||||
|
||||
const props = defineProps(['data']);
|
||||
const data = props.data;
|
||||
|
||||
const title = ref("");
|
||||
const image = ref(null);
|
||||
|
||||
const clearParent = inject('clearParent');
|
||||
|
||||
function Select(){
|
||||
if(data.id){
|
||||
GetEmitter().emit("select", data.id);
|
||||
clearParent();
|
||||
}
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
title.value = data.title;
|
||||
image.value.src = "modules/" + data.id + "/icon.png"
|
||||
})
|
||||
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<div class="system-container" v-on:click="Select">
|
||||
<img class="system-icon" ref="image">
|
||||
<div class="system-content">
|
||||
<span class="title">{{ title }}</span>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<style scoped lang="scss">
|
||||
.system-content {
|
||||
margin-left: 10px;
|
||||
width: 100%;
|
||||
text-align: left;
|
||||
align-items: center;
|
||||
display: flex;
|
||||
}
|
||||
|
||||
|
||||
.title {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.system-container {
|
||||
display: flex;
|
||||
padding: 10px;
|
||||
user-select: none;
|
||||
|
||||
transition: background-color .2s;
|
||||
|
||||
&:hover {
|
||||
background-color: var(--color-background-softer);
|
||||
}
|
||||
}
|
||||
|
||||
.system-icon {
|
||||
width: 32px;
|
||||
margin-right: auto;
|
||||
}
|
||||
</style>
|
75
client/src/views/partials/SystemSelector.vue
Normal file
75
client/src/views/partials/SystemSelector.vue
Normal file
@ -0,0 +1,75 @@
|
||||
<script setup>
|
||||
import { onMounted, onUpdated, provide, ref, watch } from 'vue';
|
||||
import { SetupHandle, SetSize, SetPosition, ResetPosition } from '@/services/Windows';
|
||||
import { CreateChildWindow } from '../../services/Windows';
|
||||
import { GetModules } from '../../services/Modules';
|
||||
|
||||
const selectedSystem = ref("");
|
||||
const selectedImage = ref(null);
|
||||
const systemTitle = ref("")
|
||||
|
||||
const props = defineProps(['windowId']);
|
||||
let windowId = props.windowId;
|
||||
|
||||
function DisplaySystemSelector(){
|
||||
CreateChildWindow(windowId, 'system_selector');
|
||||
}
|
||||
|
||||
defineExpose({ selectedSystem });
|
||||
|
||||
watch(selectedSystem, () => {
|
||||
let modules = GetModules();
|
||||
let module = null;
|
||||
modules.forEach(mod => {
|
||||
if(mod.id == selectedSystem.value) module = mod;
|
||||
});
|
||||
if(module){
|
||||
selectedImage.value.src = "modules/" + module.id + "/icon.png"
|
||||
systemTitle.value = module.title;
|
||||
}
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<div class="system-selector" v-on:click="DisplaySystemSelector">
|
||||
<span v-show="selectedSystem == ''" class="none">No game system selected</span>
|
||||
<div v-show="selectedSystem != ''" class="yes">
|
||||
<img ref="selectedImage" class="system-icon">
|
||||
{{ systemTitle }}
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
.system-selector {
|
||||
user-select: none;
|
||||
margin-top: 5px;
|
||||
margin-bottom: 5px;
|
||||
|
||||
padding: 14px;
|
||||
font-size: 15px;
|
||||
border-radius: 6px;
|
||||
outline: none;
|
||||
border: none;
|
||||
|
||||
transition: 300ms background-color;
|
||||
background-color: var(--color-background-softer);
|
||||
color: var(--color-text);
|
||||
cursor: pointer;
|
||||
}
|
||||
.none {
|
||||
color: var(--text-disabled)
|
||||
}
|
||||
.yes {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
font-weight: bold;
|
||||
}
|
||||
.system-icon {
|
||||
width: 32px;
|
||||
margin-right: auto;
|
||||
}
|
||||
</style>
|
@ -8,7 +8,16 @@ const emitter = useEmitter();
|
||||
const text = ref("");
|
||||
const toast = ref(null);
|
||||
|
||||
emitter.on('toast', data => {
|
||||
let toastQueue = [];
|
||||
let displayingToast = false;
|
||||
|
||||
function DisplayToast(){
|
||||
if(displayingToast) return;
|
||||
if(toastQueue.length == 0) return;
|
||||
|
||||
displayingToast = true;
|
||||
let data = toastQueue.pop();
|
||||
|
||||
text.value = data.text;
|
||||
|
||||
toast.value.classList.add(data.color);
|
||||
@ -20,8 +29,15 @@ emitter.on('toast', data => {
|
||||
toast.value.classList.remove("show");
|
||||
toast.value.classList.remove("sliding");
|
||||
toast.value.classList.remove(data.color);
|
||||
displayingToast = false;
|
||||
DisplayToast();
|
||||
}, 400);
|
||||
}, data.duration);
|
||||
}
|
||||
|
||||
emitter.on('toast', data => {
|
||||
toastQueue.push(data);
|
||||
DisplayToast();
|
||||
});
|
||||
|
||||
</script>
|
||||
|
@ -28,7 +28,6 @@ onMounted(() => {
|
||||
|
||||
<style scoped lang="scss">
|
||||
.book-list {
|
||||
height: 100%;
|
||||
background-color: var(--color-background);
|
||||
}
|
||||
</style>
|
@ -1,5 +1,5 @@
|
||||
<script setup>
|
||||
import { onMounted, onUpdated, ref } from 'vue';
|
||||
import { onMounted, onUpdated, ref, compile, render, h } from 'vue';
|
||||
import { SetupHandle, SetSize, SetPosition, ResetPosition } from '@/services/Windows';
|
||||
|
||||
import WindowHandle from '@/views/partials/WindowHandle.vue';
|
||||
@ -10,6 +10,9 @@ const props = defineProps(['data']);
|
||||
const data = props.data;
|
||||
|
||||
let id = data.id;
|
||||
|
||||
const test = ref(null)
|
||||
|
||||
onMounted(() => {
|
||||
SetupHandle(id, handle);
|
||||
SetSize(id, {x: 500, y: 380});
|
||||
@ -23,6 +26,7 @@ onMounted(() => {
|
||||
<WindowHandle :window="id" ref="handle"></WindowHandle>
|
||||
|
||||
<!-- Body -->
|
||||
<div ref="test"></div>
|
||||
|
||||
</div>
|
||||
</template>
|
||||
@ -30,29 +34,9 @@ onMounted(() => {
|
||||
|
||||
<style scoped>
|
||||
.window-wrapper {
|
||||
min-width: 700px;
|
||||
min-height: 630px;
|
||||
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.splash-image {
|
||||
width: 600px;
|
||||
height: 250px;
|
||||
}
|
||||
|
||||
.form-field {
|
||||
padding: 10px;
|
||||
display: flex;
|
||||
align-items: left;
|
||||
flex-direction: column;
|
||||
justify-content: left;
|
||||
width: 600px;
|
||||
}
|
||||
|
||||
label {
|
||||
text-align: left;
|
||||
}
|
||||
|
||||
</style>
|
||||
|
||||
|
||||
|
@ -7,6 +7,7 @@ import { CreateWindow, CreateChildWindow } from '../../../services/Windows';
|
||||
|
||||
import Api from '@/services/Api.js'
|
||||
import CampaignEntry from '../../partials/CampaignEntry.vue';
|
||||
import { GetEmitter } from '../../../services/Dragonroll';
|
||||
|
||||
const handle = ref(null);
|
||||
|
||||
@ -23,6 +24,8 @@ onMounted(() => {
|
||||
ResetPosition(id, "center");
|
||||
|
||||
RefreshCampaigns();
|
||||
|
||||
GetEmitter().on('refresh_campaign', () => { RefreshCampaigns() });
|
||||
});
|
||||
|
||||
function CreateCampaign(){
|
||||
|
@ -10,6 +10,8 @@ import { ClearAll, ClearWindow, CreateWindow } from '../../../services/Windows';
|
||||
import { LaunchGame } from '../../../services/Game';
|
||||
import { AddSound } from '../../../services/Sound';
|
||||
import ChatComponent from '../../partials/ChatComponent.vue';
|
||||
import GameSystem from '@/views/partials/GameSystem.vue'
|
||||
import { GetModule } from '../../../services/Modules';
|
||||
|
||||
const handle = ref(null);
|
||||
|
||||
@ -18,6 +20,7 @@ const data = props.data;
|
||||
|
||||
const hide_start = ref(false);
|
||||
const hide_chat = ref(false);
|
||||
const campaign_title = ref(null);
|
||||
|
||||
const container = ref(null);
|
||||
|
||||
@ -37,6 +40,8 @@ onMounted(() => {
|
||||
hide_start.value = data.hide_start;
|
||||
|
||||
AddSound(container.value)
|
||||
|
||||
campaign_title.value.style.backgroundColor = GetModule(data.campaign.system).color ? GetModule(data.campaign.system).color : "#1f1f1f";
|
||||
});
|
||||
|
||||
function CopyCode(){
|
||||
@ -74,10 +79,10 @@ function Exit(){
|
||||
</div>
|
||||
</div>
|
||||
<div class="campaign-preview-column center">
|
||||
<h1 class="campaign-title">{{ data.campaign.name }}</h1>
|
||||
<h1 class="campaign-title" ref="campaign_title">{{ data.campaign.name }}</h1>
|
||||
<div class="campaign-main-container">
|
||||
<div class="campaign-main-container-scroll">
|
||||
<div class="">Dnd 5e</div>
|
||||
<GameSystem :data="GetModule(data.campaign.system)"></GameSystem>
|
||||
<h2>Books</h2>
|
||||
<CampaignBookList class="small-book-list"></CampaignBookList>
|
||||
</div>
|
||||
@ -98,7 +103,6 @@ function Exit(){
|
||||
|
||||
<style scoped lang="scss">
|
||||
.small-book-list {
|
||||
height: 400px;
|
||||
margin: 20px;
|
||||
overflow: auto;
|
||||
}
|
||||
@ -137,10 +141,10 @@ function Exit(){
|
||||
height: 100%;
|
||||
|
||||
display: grid;
|
||||
grid-template-columns: 3fr 5fr 4fr;
|
||||
grid-template-columns: 2fr 4fr 3fr;
|
||||
|
||||
&.campaign-preview-compact {
|
||||
grid-template-columns: 2fr 3fr;
|
||||
grid-template-columns: 2fr 4fr;
|
||||
}
|
||||
}
|
||||
|
||||
@ -173,4 +177,8 @@ h1, h2 {
|
||||
font-family: MrEavesRemake;
|
||||
}
|
||||
|
||||
h1 {
|
||||
background-color: rgb(143, 39, 39);
|
||||
}
|
||||
|
||||
</style>
|
||||
|
@ -1,10 +1,13 @@
|
||||
<script setup>
|
||||
import { onMounted, onUpdated, ref } from 'vue';
|
||||
import { SetupHandle, SetSize, SetPosition, ResetPosition } from '@/services/Windows';
|
||||
import { onMounted, onUpdated, ref, provide } from 'vue';
|
||||
import { SetupHandle, SetSize, SetPosition, ResetPosition, ClearWindow } from '@/services/Windows';
|
||||
|
||||
import WindowHandle from '@/views/partials/WindowHandle.vue';
|
||||
import ErrorMessage from '@/components/partials/ErrorMessage.vue'
|
||||
|
||||
import Api from '@/services/Api.js'
|
||||
import SystemSelector from '../../partials/SystemSelector.vue';
|
||||
import { GetEmitter } from '../../../services/Dragonroll';
|
||||
|
||||
const handle = ref(null);
|
||||
|
||||
@ -12,20 +15,41 @@ const props = defineProps(['data']);
|
||||
const data = props.data;
|
||||
|
||||
const campaignName = ref("");
|
||||
const systemSelector = ref(null);
|
||||
|
||||
const errorMessage = ref("");
|
||||
|
||||
let id = data.id;
|
||||
let system = "";
|
||||
|
||||
onMounted(() => {
|
||||
SetupHandle(id, handle);
|
||||
SetSize(id, {x: 300, y: 150});
|
||||
SetSize(id, {x: 300, y: 240});
|
||||
ResetPosition(id, "center");
|
||||
GetEmitter().on('select', (system_id) => Select(system_id))
|
||||
|
||||
console.log(system);
|
||||
});
|
||||
|
||||
function Select(system_id){
|
||||
system = system_id;
|
||||
try {
|
||||
systemSelector.value.selectedSystem = system_id;
|
||||
} catch {}
|
||||
}
|
||||
|
||||
|
||||
function NewCampaign(){
|
||||
Api().post('/campaign/create', {
|
||||
name: campaignName.value
|
||||
name: campaignName.value,
|
||||
system
|
||||
}).then((response) => {
|
||||
console.log(response);
|
||||
if(response.data.status == "error"){
|
||||
errorMessage.value = response.data.msg;
|
||||
} else {
|
||||
ClearWindow(id);
|
||||
GetEmitter().emit('refresh_campaign');
|
||||
}
|
||||
});
|
||||
}
|
||||
</script>
|
||||
@ -40,10 +64,15 @@ function NewCampaign(){
|
||||
<div class="form-field">
|
||||
<input id="username-field" type="text" placeholder="Enter campaign name..." name="campaignName" v-model="campaignName" autocomplete="off" >
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<SystemSelector :windowId="id" ref="systemSelector"></SystemSelector>
|
||||
</div>
|
||||
<div class="form-field">
|
||||
<button class="btn-primary sound-click">Create</button>
|
||||
</div>
|
||||
</form>
|
||||
|
||||
<ErrorMessage v-if="errorMessage">{{ errorMessage }}</ErrorMessage>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
63
client/src/views/windows/campaigns/SystemSelectorWindow.vue
Normal file
63
client/src/views/windows/campaigns/SystemSelectorWindow.vue
Normal file
@ -0,0 +1,63 @@
|
||||
<script setup>
|
||||
import { onMounted, onUpdated, provide, ref, inject } from 'vue';
|
||||
import { SetupHandle, SetSize, SetPosition, ResetPosition } from '@/services/Windows';
|
||||
|
||||
import WindowHandle from '@/views/partials/WindowHandle.vue';
|
||||
|
||||
import Api from '@/services/Api.js'
|
||||
import SystemSelector from '../../partials/SystemSelector.vue';
|
||||
import { GetModules } from '../../../services/Modules';
|
||||
import GameSystem from '../../partials/GameSystem.vue';
|
||||
import { ClearWindow } from '../../../services/Windows';
|
||||
|
||||
const handle = ref(null);
|
||||
|
||||
const props = defineProps(['data']);
|
||||
const data = props.data;
|
||||
|
||||
const campaignName = ref("");
|
||||
|
||||
let id = data.id;
|
||||
let systems = ref(GetModules());
|
||||
|
||||
function Clear(){
|
||||
ClearWindow(id);
|
||||
}
|
||||
|
||||
provide('clearParent', Clear);
|
||||
|
||||
onMounted(() => {
|
||||
SetupHandle(id, handle);
|
||||
SetSize(id, {x: 300, y: 600});
|
||||
ResetPosition(id, "center");
|
||||
|
||||
console.log(systems.value)
|
||||
});
|
||||
</script>
|
||||
|
||||
|
||||
<template>
|
||||
<div class="window-wrapper" :id="'window-wrapper-' + id">
|
||||
<WindowHandle :window="id" ref="handle"></WindowHandle>
|
||||
|
||||
<!-- Body -->
|
||||
<div class="system-list">
|
||||
<GameSystem v-for="system in systems" :id="system.id" :data="system"></GameSystem>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
|
||||
<style scoped lang="scss">
|
||||
.window-wrapper {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
}
|
||||
|
||||
.system-list {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
width: 100%;
|
||||
}
|
||||
|
||||
</style>
|
@ -11,6 +11,7 @@ export default defineConfig({
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': fileURLToPath(new URL('./src', import.meta.url)),
|
||||
'vue': 'vue/dist/vue.esm-bundler.js'
|
||||
}
|
||||
},
|
||||
proxy: {
|
||||
|
12
server/models/Book.js
Normal file
12
server/models/Book.js
Normal file
@ -0,0 +1,12 @@
|
||||
const mongoose = require("mongoose");
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const BookSchema = new Schema({
|
||||
title: {type: String, required: true},
|
||||
authors: { type: [String] },
|
||||
system: {type: String, required: true},
|
||||
image: { type: String },
|
||||
data: { type: Object },
|
||||
});
|
||||
|
||||
module.exports = mongoose.model('Book', BookSchema);
|
@ -3,6 +3,7 @@ const Schema = mongoose.Schema;
|
||||
|
||||
const CampaignSchema = new Schema({
|
||||
name: {type: String, required: true},
|
||||
system: {type: String, required: true},
|
||||
creation_date: { type: Date, default: Date.now},
|
||||
last_opened: { type: Date, default: Date.now},
|
||||
invite_code: { type: String, unique: true },
|
||||
|
11
server/models/Character.js
Normal file
11
server/models/Character.js
Normal file
@ -0,0 +1,11 @@
|
||||
const mongoose = require("mongoose");
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const CharacterSchema = new Schema({
|
||||
name: {type: String, required: true},
|
||||
data: { type: Object },
|
||||
campaign_user: {type: mongoose.Types.ObjectId, ref: "CampaignUser"},
|
||||
image: { type: String },
|
||||
});
|
||||
|
||||
module.exports = mongoose.model('Character', CharacterSchema);
|
11
server/models/Entity.js
Normal file
11
server/models/Entity.js
Normal file
@ -0,0 +1,11 @@
|
||||
const mongoose = require("mongoose");
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const EntitySchema = new Schema({
|
||||
name: {type: String, required: true},
|
||||
data: { type: Object },
|
||||
campaign: {type: mongoose.Types.ObjectId, ref: "Campaign"},
|
||||
image: { type: String },
|
||||
});
|
||||
|
||||
module.exports = mongoose.model('Entity', EntitySchema);
|
12
server/models/Map.js
Normal file
12
server/models/Map.js
Normal file
@ -0,0 +1,12 @@
|
||||
const mongoose = require("mongoose");
|
||||
const Schema = mongoose.Schema;
|
||||
|
||||
const MapSchema = new Schema({
|
||||
name: {type: String, required: true},
|
||||
data: { type: Object }, // Data del format dd2vtt
|
||||
campaign: {type: mongoose.Types.ObjectId, ref: "Campaign"},
|
||||
image: { type: String },
|
||||
entities: { type: Object }
|
||||
});
|
||||
|
||||
module.exports = mongoose.model('Entity', EntitySchema);
|
@ -16,10 +16,11 @@ router.post('/register', passport.authenticate('jwt', {session: false}), rateLim
|
||||
|
||||
router.post('/create', passport.authenticate('jwt', {session: false}), rateLimitMiddleware, (req, res) => {
|
||||
let {
|
||||
name
|
||||
name,
|
||||
system
|
||||
} = req.body;
|
||||
|
||||
if(!(name)){
|
||||
if(!(name && system)){
|
||||
res.json({
|
||||
status: "error",
|
||||
msg: "params"
|
||||
@ -28,7 +29,7 @@ router.post('/create', passport.authenticate('jwt', {session: false}), rateLimit
|
||||
}
|
||||
|
||||
// Create the campaign
|
||||
let campaign = new Campaign({name});
|
||||
let campaign = new Campaign({name, system});
|
||||
campaign.invite_code = Campaign.generateInvite();
|
||||
|
||||
campaign.save().then(campaign => {
|
||||
|
Loading…
Reference in New Issue
Block a user