Greatly improved look and feel of site navigation
This commit is contained in:
@@ -140,3 +140,13 @@ Meteor.users.findUserByUsernameOrEmail = new ValidatedMethod({
|
||||
return user && user._id;
|
||||
}
|
||||
});
|
||||
|
||||
export function getEntitledCentsOfUser(user){
|
||||
if (!user) return 0;
|
||||
const patreon = user.services && user.services.patreon;
|
||||
if (!patreon) return 0;
|
||||
let entitledCents = patreon.entitledCents || 0;
|
||||
let overrideCents = patreon.entitledCentsOverride || 0;
|
||||
if (overrideCents > entitledCents) entitledCents = overrideCents;
|
||||
return entitledCents;
|
||||
}
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
<template lang="html" functional>
|
||||
<template
|
||||
lang="html"
|
||||
functional
|
||||
>
|
||||
<div class="column-layout">
|
||||
<slot/>
|
||||
<slot />
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -11,7 +14,7 @@ export default {
|
||||
|
||||
<style lang="css" scoped>
|
||||
.column-layout {
|
||||
column-count: 4;
|
||||
column-count: 12;
|
||||
column-fill: balance;
|
||||
column-gap: 0;
|
||||
column-width: 240px;
|
||||
|
||||
@@ -1,33 +1,34 @@
|
||||
<template lang="html">
|
||||
<div class="creature-form">
|
||||
<text-field
|
||||
label="Name"
|
||||
:value="model.name"
|
||||
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
|
||||
:error-messages="errors.name"
|
||||
:debounce-time="debounceTime"
|
||||
/>
|
||||
<text-field
|
||||
label="Alignment"
|
||||
:value="model.alignment"
|
||||
@change="(value, ack) => $emit('change', {path: ['alignment'], value, ack})"
|
||||
:error-messages="errors.alignment"
|
||||
:debounce-time="debounceTime"
|
||||
/>
|
||||
<text-field
|
||||
label="Gender"
|
||||
:value="model.gender"
|
||||
@change="(value, ack) => $emit('change', {path: ['gender'], value, ack})"
|
||||
:error-messages="errors.gender"
|
||||
:debounce-time="debounceTime"
|
||||
/>
|
||||
<text-field
|
||||
label="Picture URL"
|
||||
:value="model.picture"
|
||||
@change="(value, ack) => $emit('change', {path: ['picture'], value, ack})"
|
||||
:error-messages="errors.picture"
|
||||
:debounce-time="debounceTime"
|
||||
/>
|
||||
<div class="creature-form">
|
||||
<text-field
|
||||
label="Name"
|
||||
:value="model.name"
|
||||
:error-messages="errors.name"
|
||||
:debounce-time="debounceTime"
|
||||
@change="(value, ack) => $emit('change', {path: ['name'], value, ack})"
|
||||
/>
|
||||
<text-field
|
||||
label="Alignment"
|
||||
:value="model.alignment"
|
||||
:error-messages="errors.alignment"
|
||||
:debounce-time="debounceTime"
|
||||
@change="(value, ack) => $emit('change', {path: ['alignment'], value, ack})"
|
||||
/>
|
||||
<text-field
|
||||
label="Gender"
|
||||
:value="model.gender"
|
||||
:error-messages="errors.gender"
|
||||
:debounce-time="debounceTime"
|
||||
@change="(value, ack) => $emit('change', {path: ['gender'], value, ack})"
|
||||
/>
|
||||
<text-field
|
||||
label="Picture URL"
|
||||
:value="model.picture"
|
||||
:error-messages="errors.picture"
|
||||
:debounce-time="debounceTime"
|
||||
@change="(value, ack) => $emit('change', {path: ['picture'], value, ack})"
|
||||
/>
|
||||
<!--
|
||||
<form-sections>
|
||||
<form-section name="settings">
|
||||
<v-switch
|
||||
@@ -50,7 +51,8 @@
|
||||
/>
|
||||
</form-section>
|
||||
</form-sections>
|
||||
</div>
|
||||
-->
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
|
||||
@@ -1,115 +1,46 @@
|
||||
<template>
|
||||
<div class="character-sheet layout column">
|
||||
<v-toolbar
|
||||
app
|
||||
clipped-left
|
||||
:color="creature.color || 'secondary'"
|
||||
:dark="isDarkColor(creature.color || theme.primary)"
|
||||
>
|
||||
<v-btn
|
||||
v-if="showMenuButton"
|
||||
flat
|
||||
icon
|
||||
@click="toggleDrawer"
|
||||
<div class="character-sheet fill-height">
|
||||
<v-fade-transition mode="out-in">
|
||||
<div
|
||||
v-if="$subReady.singleCharacter"
|
||||
key="character-tabs"
|
||||
class="fill-height"
|
||||
>
|
||||
<v-icon>menu</v-icon>
|
||||
</v-btn>
|
||||
<div class="flex">
|
||||
{{ creature.name }}
|
||||
<v-tabs-items
|
||||
v-model="tabs"
|
||||
>
|
||||
<v-tab-item>
|
||||
<stats-tab :creature-id="creatureId" />
|
||||
</v-tab-item>
|
||||
<v-tab-item>
|
||||
<features-tab :creature-id="creatureId" />
|
||||
</v-tab-item>
|
||||
<v-tab-item>
|
||||
<inventory-tab :creature-id="creatureId" />
|
||||
</v-tab-item>
|
||||
<v-tab-item>
|
||||
<spells-tab :creature-id="creatureId" />
|
||||
</v-tab-item>
|
||||
<v-tab-item>
|
||||
<persona-tab :creature-id="creatureId" />
|
||||
</v-tab-item>
|
||||
<v-tab-item>
|
||||
<tree-tab :creature-id="creatureId" />
|
||||
</v-tab-item>
|
||||
</v-tabs-items>
|
||||
</div>
|
||||
<v-btn
|
||||
flat
|
||||
icon
|
||||
@click="recompute(creature._id)"
|
||||
<div
|
||||
v-else
|
||||
key="character-loading"
|
||||
class="fill-height layout justify-center align-center"
|
||||
>
|
||||
<v-icon>refresh</v-icon>
|
||||
</v-btn>
|
||||
<v-menu
|
||||
bottom
|
||||
left
|
||||
transition="slide-y-transition"
|
||||
data-id="creature-menu"
|
||||
>
|
||||
<template #activator="{ on }">
|
||||
<v-btn
|
||||
icon
|
||||
v-on="on"
|
||||
>
|
||||
<v-icon>more_vert</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-list>
|
||||
<v-list-tile @click="deleteCharacter">
|
||||
<v-list-tile-title>
|
||||
<v-icon>delete</v-icon> Delete
|
||||
</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
<v-list-tile @click="showCharacterForm">
|
||||
<v-list-tile-title>
|
||||
<v-icon>create</v-icon> Edit details
|
||||
</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
<v-list-tile @click="showShareDialog">
|
||||
<v-list-tile-title>
|
||||
<v-icon>share</v-icon> Sharing
|
||||
</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
<v-tabs
|
||||
slot="extension"
|
||||
v-model="tab"
|
||||
centered
|
||||
grow
|
||||
>
|
||||
<v-tab>
|
||||
Stats
|
||||
</v-tab>
|
||||
<v-tab>
|
||||
Features
|
||||
</v-tab>
|
||||
<v-tab>
|
||||
Inventory
|
||||
</v-tab>
|
||||
<v-tab>
|
||||
Spells
|
||||
</v-tab>
|
||||
<v-tab>
|
||||
Persona
|
||||
</v-tab>
|
||||
<v-tab>
|
||||
Tree
|
||||
</v-tab>
|
||||
</v-tabs>
|
||||
</v-toolbar>
|
||||
<v-content
|
||||
v-if="$subReady.singleCharacter"
|
||||
class="flex"
|
||||
>
|
||||
<v-tabs-items v-model="tab">
|
||||
<v-tab-item>
|
||||
<stats-tab :creature-id="creatureId" />
|
||||
</v-tab-item>
|
||||
<v-tab-item>
|
||||
<features-tab :creature-id="creatureId" />
|
||||
</v-tab-item>
|
||||
<v-tab-item>
|
||||
<inventory-tab :creature-id="creatureId" />
|
||||
</v-tab-item>
|
||||
<v-tab-item>
|
||||
<spells-tab :creature-id="creatureId" />
|
||||
</v-tab-item>
|
||||
<v-tab-item>
|
||||
<persona-tab :creature-id="creatureId" />
|
||||
</v-tab-item>
|
||||
<v-tab-item>
|
||||
<tree-tab :creature-id="creatureId" />
|
||||
</v-tab-item>
|
||||
</v-tabs-items>
|
||||
</v-content>
|
||||
<v-content v-else>
|
||||
<v-progress-circular indeterminate />
|
||||
</v-content>
|
||||
<v-progress-circular
|
||||
indeterminate
|
||||
color="primary"
|
||||
size="64"
|
||||
/>
|
||||
</div>
|
||||
</v-fade-transition>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
@@ -139,70 +70,26 @@
|
||||
TreeTab,
|
||||
},
|
||||
props: {
|
||||
showMenuButton: Boolean,
|
||||
creatureId: {
|
||||
type: String,
|
||||
required: true,
|
||||
},
|
||||
tabs: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
reactiveProvide: {
|
||||
name: 'computationContext',
|
||||
include: ['creature'],
|
||||
},
|
||||
data(){return {
|
||||
theme,
|
||||
tab: 0,
|
||||
}},
|
||||
methods: {
|
||||
...mapMutations([
|
||||
'toggleDrawer',
|
||||
]),
|
||||
recompute(charId){
|
||||
recomputeCreature.call({charId});
|
||||
},
|
||||
showCharacterForm(){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'creature-form-dialog',
|
||||
elementId: 'creature-menu',
|
||||
data: {
|
||||
_id: this.creatureId,
|
||||
},
|
||||
});
|
||||
},
|
||||
showShareDialog(){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'share-dialog',
|
||||
elementId: 'creature-menu',
|
||||
data: {
|
||||
docRef: {
|
||||
id: this.creatureId,
|
||||
collection: 'creatures',
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
deleteCharacter(){
|
||||
let that = this;
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'delete-confirmation-dialog',
|
||||
elementId: 'creature-menu',
|
||||
data: {
|
||||
name: this.creature.name,
|
||||
typeName: 'Character'
|
||||
},
|
||||
callback(confirmation){
|
||||
if(!confirmation) return;
|
||||
removeCreature.call({charId: that.creatureId}, (error) => {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
} else {
|
||||
that.$router.push('/characterList');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
isDarkColor,
|
||||
onMounted(){
|
||||
this.$store.commit('setPageTitle', this.creature && this.creature.name || 'Character Sheet');
|
||||
},
|
||||
watch: {
|
||||
'creature.name'(value){
|
||||
this.$store.commit('setPageTitle', value || 'Character Sheet');
|
||||
},
|
||||
},
|
||||
meteor: {
|
||||
$subscribe: {
|
||||
@@ -216,18 +103,3 @@
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style>
|
||||
.v-tabs__bar {
|
||||
background: none !important;
|
||||
}
|
||||
.v-tabs__container--grow .v-tabs__div {
|
||||
max-width: 180px !important;
|
||||
}
|
||||
.v-window-item, .v-window, .v-window__container {
|
||||
height: 100%;
|
||||
}
|
||||
.v-window-item {
|
||||
padding: 0.1px;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -0,0 +1,46 @@
|
||||
<template lang="html">
|
||||
<v-tabs
|
||||
slot="extension"
|
||||
:value="value"
|
||||
centered
|
||||
grow
|
||||
max="100px"
|
||||
@change="e => $emit('input', e)"
|
||||
>
|
||||
<v-tab>
|
||||
Stats
|
||||
</v-tab>
|
||||
<v-tab>
|
||||
Features
|
||||
</v-tab>
|
||||
<v-tab>
|
||||
Inventory
|
||||
</v-tab>
|
||||
<v-tab>
|
||||
Spells
|
||||
</v-tab>
|
||||
<v-tab>
|
||||
Persona
|
||||
</v-tab>
|
||||
<v-tab>
|
||||
Tree
|
||||
</v-tab>
|
||||
</v-tabs>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
export default {
|
||||
props: {
|
||||
value: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
.v-tabs__container--grow .v-tabs__div {
|
||||
max-width: 120px !important;
|
||||
}
|
||||
</style>
|
||||
127
app/imports/ui/creature/character/CharacterSheetToolbarItems.vue
Normal file
127
app/imports/ui/creature/character/CharacterSheetToolbarItems.vue
Normal file
@@ -0,0 +1,127 @@
|
||||
<template lang="html">
|
||||
<v-toolbar-items>
|
||||
<v-btn
|
||||
flat
|
||||
icon
|
||||
@click="recompute(creature._id)"
|
||||
>
|
||||
<v-icon>refresh</v-icon>
|
||||
</v-btn>
|
||||
<v-menu
|
||||
bottom
|
||||
left
|
||||
transition="slide-y-transition"
|
||||
data-id="creature-menu"
|
||||
>
|
||||
<template #activator="{ on }">
|
||||
<v-btn
|
||||
icon
|
||||
v-on="on"
|
||||
>
|
||||
<v-icon>more_vert</v-icon>
|
||||
</v-btn>
|
||||
</template>
|
||||
<v-list>
|
||||
<v-list-tile @click="deleteCharacter">
|
||||
<v-list-tile-title>
|
||||
<v-icon>delete</v-icon> Delete
|
||||
</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
<v-list-tile @click="showCharacterForm">
|
||||
<v-list-tile-title>
|
||||
<v-icon>create</v-icon> Edit details
|
||||
</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
<v-list-tile @click="showShareDialog">
|
||||
<v-list-tile-title>
|
||||
<v-icon>share</v-icon> Sharing
|
||||
</v-list-tile-title>
|
||||
</v-list-tile>
|
||||
</v-list>
|
||||
</v-menu>
|
||||
</v-toolbar-items>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Creatures from '/imports/api/creature/Creatures.js';
|
||||
import removeCreature from '/imports/api/creature/removeCreature.js';
|
||||
import isDarkColor from '/imports/ui/utility/isDarkColor.js';
|
||||
import { mapMutations } from 'vuex';
|
||||
import { theme } from '/imports/ui/theme.js';
|
||||
import { recomputeCreature } from '/imports/api/creature/computation/recomputeCreature.js';
|
||||
|
||||
export default {
|
||||
data(){return {
|
||||
theme,
|
||||
}},
|
||||
methods: {
|
||||
...mapMutations([
|
||||
'toggleDrawer',
|
||||
]),
|
||||
recompute(charId){
|
||||
recomputeCreature.call({charId});
|
||||
},
|
||||
showCharacterForm(){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'creature-form-dialog',
|
||||
elementId: 'creature-menu',
|
||||
data: {
|
||||
_id: this.creatureId,
|
||||
},
|
||||
});
|
||||
},
|
||||
showShareDialog(){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'share-dialog',
|
||||
elementId: 'creature-menu',
|
||||
data: {
|
||||
docRef: {
|
||||
id: this.creatureId,
|
||||
collection: 'creatures',
|
||||
}
|
||||
},
|
||||
});
|
||||
},
|
||||
deleteCharacter(){
|
||||
let that = this;
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'delete-confirmation-dialog',
|
||||
elementId: 'creature-menu',
|
||||
data: {
|
||||
name: this.creature.name,
|
||||
typeName: 'Character'
|
||||
},
|
||||
callback(confirmation){
|
||||
if(!confirmation) return;
|
||||
removeCreature.call({charId: that.creatureId}, (error) => {
|
||||
if (error) {
|
||||
console.error(error);
|
||||
} else {
|
||||
that.$router.push('/characterList');
|
||||
}
|
||||
});
|
||||
}
|
||||
});
|
||||
},
|
||||
isDarkColor,
|
||||
},
|
||||
computed: {
|
||||
creatureId(){
|
||||
return this.$route.params.id;
|
||||
},
|
||||
},
|
||||
meteor: {
|
||||
$subscribe: {
|
||||
'singleCharacter'(){
|
||||
return [this.creatureId];
|
||||
},
|
||||
},
|
||||
creature(){
|
||||
return Creatures.findOne(this.creatureId) || {};
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
</style>
|
||||
@@ -1,83 +1,96 @@
|
||||
<template lang="html">
|
||||
<toolbar-layout>
|
||||
<div slot="toolbar">
|
||||
DiceCloud
|
||||
</div>
|
||||
<div>
|
||||
<div class="content">
|
||||
<v-card class="ma-4">
|
||||
<v-card-text>
|
||||
<v-layout column align-center>
|
||||
<upload-btn
|
||||
:fileChangedCallback="fileChanged"
|
||||
/>
|
||||
<v-text-field
|
||||
label="Search"
|
||||
@click:append="updateSearchString"
|
||||
@keydown.enter="updateSearchString"
|
||||
ref="iconSearchField"
|
||||
append-icon="search"
|
||||
/>
|
||||
<v-container grid-list-md fill-height>
|
||||
<v-layout row wrap>
|
||||
<v-flex xs3 md2 xl1 v-for="icon in icons" :key="icon._id._str || icon._id">
|
||||
<v-card>
|
||||
<v-card-title class="title">{{icon.name}}</v-card-title>
|
||||
<v-card-text>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 512 512"><path fill="#000" :d="icon.shape"/></svg>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
</v-layout>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</div>
|
||||
</toolbar-layout>
|
||||
<v-card class="ma-4">
|
||||
<v-card-text>
|
||||
<v-layout
|
||||
column
|
||||
align-center
|
||||
>
|
||||
<upload-btn
|
||||
:file-changed-callback="fileChanged"
|
||||
/>
|
||||
<v-text-field
|
||||
ref="iconSearchField"
|
||||
label="Search"
|
||||
append-icon="search"
|
||||
@click:append="updateSearchString"
|
||||
@keydown.enter="updateSearchString"
|
||||
/>
|
||||
<v-container
|
||||
grid-list-md
|
||||
fill-height
|
||||
>
|
||||
<v-layout
|
||||
row
|
||||
wrap
|
||||
>
|
||||
<v-flex
|
||||
v-for="icon in icons"
|
||||
:key="icon._id._str || icon._id"
|
||||
xs3
|
||||
md2
|
||||
xl1
|
||||
>
|
||||
<v-card>
|
||||
<v-card-title class="title">
|
||||
{{ icon.name }}
|
||||
</v-card-title>
|
||||
<v-card-text>
|
||||
<svg
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
viewBox="0 0 512 512"
|
||||
><path
|
||||
fill="#000"
|
||||
:d="icon.shape"
|
||||
/></svg>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</v-flex>
|
||||
</v-layout>
|
||||
</v-container>
|
||||
</v-layout>
|
||||
</v-card-text>
|
||||
</v-card>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import UploadButton from 'vuetify-upload-button';
|
||||
import ToolbarLayout from "/imports/ui/layouts/ToolbarLayout.vue";
|
||||
import importIcons from '/imports/ui/icons/importIcons.js';
|
||||
import Icons from '/imports/api/icons/Icons.js';
|
||||
import { _ } from 'meteor/underscore';
|
||||
import importIcons from '/imports/ui/icons/importIcons.js';
|
||||
import Icons from '/imports/api/icons/Icons.js';
|
||||
|
||||
export default {
|
||||
data(){ return {
|
||||
searchString: '',
|
||||
}},
|
||||
methods: {
|
||||
export default {
|
||||
data(){ return {
|
||||
searchString: '',
|
||||
}},
|
||||
methods: {
|
||||
fileChanged (file) {
|
||||
importIcons(file);
|
||||
importIcons(file);
|
||||
},
|
||||
updateSearchString(){
|
||||
this.searchString = this.$refs.iconSearchField.internalValue;
|
||||
},
|
||||
updateSearchString(){
|
||||
this.searchString = this.$refs.iconSearchField.internalValue;
|
||||
},
|
||||
},
|
||||
components: {
|
||||
ToolbarLayout,
|
||||
'upload-btn': UploadButton
|
||||
meteor: {
|
||||
$subscribe: {
|
||||
searchIcons() {
|
||||
return [this.searchString];
|
||||
},
|
||||
},
|
||||
icons(){
|
||||
return Icons.find({}, { sort: [['score', 'desc']] });
|
||||
},
|
||||
},
|
||||
meteor: {
|
||||
$subscribe: {
|
||||
searchIcons() {
|
||||
return [this.searchString];
|
||||
},
|
||||
},
|
||||
icons(){
|
||||
return Icons.find({}, { sort: [["score", "desc"]] });
|
||||
},
|
||||
},
|
||||
};
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
svg {
|
||||
height: 64px;
|
||||
width: 64px;
|
||||
height: 64px;
|
||||
width: 64px;
|
||||
}
|
||||
.v-card {
|
||||
height: 100%;
|
||||
}
|
||||
.v-card {
|
||||
height: 100%;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,19 +1,84 @@
|
||||
<template>
|
||||
<v-app :dark="darkMode" :light="!darkMode">
|
||||
<v-navigation-drawer app v-model="drawer" clipped>
|
||||
<Sidebar/>
|
||||
<v-app
|
||||
:dark="darkMode"
|
||||
:light="!darkMode"
|
||||
>
|
||||
<v-navigation-drawer
|
||||
v-model="drawer"
|
||||
app
|
||||
>
|
||||
<Sidebar />
|
||||
</v-navigation-drawer>
|
||||
<router-view></router-view>
|
||||
<dialog-stack></dialog-stack>
|
||||
<v-toolbar
|
||||
app
|
||||
color="secondary"
|
||||
dark
|
||||
tabs
|
||||
dense
|
||||
>
|
||||
<v-toolbar-side-icon @click="toggleDrawer" />
|
||||
<v-toolbar-title>
|
||||
<v-fade-transition
|
||||
mode="out-in"
|
||||
>
|
||||
<div :key="$store.state.pageTitle">
|
||||
{{ $store.state.pageTitle }}
|
||||
</div>
|
||||
</v-fade-transition>
|
||||
</v-toolbar-title>
|
||||
<v-spacer />
|
||||
<v-fade-transition
|
||||
mode="out-in"
|
||||
>
|
||||
<div :key="$route.meta.title">
|
||||
<router-view
|
||||
name="toolbarItems"
|
||||
/>
|
||||
</div>
|
||||
</v-fade-transition>
|
||||
<v-fade-transition
|
||||
slot="extension"
|
||||
mode="out-in"
|
||||
>
|
||||
<div
|
||||
:key="$route.meta.title"
|
||||
style="width: 100%"
|
||||
>
|
||||
<router-view
|
||||
v-model="tabs"
|
||||
name="toolbarExtension"
|
||||
/>
|
||||
</div>
|
||||
</v-fade-transition>
|
||||
</v-toolbar>
|
||||
<v-content>
|
||||
<v-fade-transition
|
||||
mode="out-in"
|
||||
>
|
||||
<router-view :tabs="tabs" />
|
||||
</v-fade-transition>
|
||||
</v-content>
|
||||
|
||||
<dialog-stack />
|
||||
</v-app>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import '/imports/api/users/Users.js';
|
||||
import Sidebar from "/imports/ui/layouts/Sidebar.vue";
|
||||
import DialogStack from "/imports/ui/dialogStack/DialogStack.vue";
|
||||
import Sidebar from '/imports/ui/layouts/Sidebar.vue';
|
||||
import DialogStack from '/imports/ui/dialogStack/DialogStack.vue';
|
||||
import { theme, darkTheme } from '/imports/ui/theme.js';
|
||||
import { mapMutations } from 'vuex';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
Sidebar,
|
||||
DialogStack,
|
||||
},
|
||||
data(){return {
|
||||
name: 'Home',
|
||||
tabs: 0,
|
||||
}},
|
||||
computed: {
|
||||
drawer: {
|
||||
get () {
|
||||
@@ -23,15 +88,8 @@
|
||||
this.$store.commit('setDrawer', value);
|
||||
},
|
||||
},
|
||||
},
|
||||
components: {
|
||||
Sidebar,
|
||||
DialogStack,
|
||||
},
|
||||
meteor: {
|
||||
$subscribe: {
|
||||
'user': [],
|
||||
},
|
||||
darkMode(){
|
||||
let user = Meteor.user();
|
||||
return user && user.darkMode;
|
||||
@@ -47,10 +105,17 @@
|
||||
}
|
||||
},
|
||||
},
|
||||
'$route' (to) {
|
||||
this.$store.commit('setPageTitle', to.meta && to.meta.title || 'DiceCloud');
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations([
|
||||
'toggleDrawer',
|
||||
]),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
<style>
|
||||
|
||||
</style>
|
||||
|
||||
@@ -50,7 +50,6 @@
|
||||
|
||||
<v-list-tile
|
||||
v-for="(link, i) in links"
|
||||
v-if="link.vif || link.vif === undefined"
|
||||
:key="i"
|
||||
:to="link.to"
|
||||
:href="link.href"
|
||||
@@ -98,70 +97,73 @@
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Creatures from '/imports/api/creature/Creatures.js';
|
||||
import Parties from '/imports/api/campaign/Parties.js';
|
||||
import Creatures from '/imports/api/creature/Creatures.js';
|
||||
import Parties from '/imports/api/campaign/Parties.js';
|
||||
|
||||
export default {
|
||||
data(){return {
|
||||
showWarning: true,
|
||||
}},
|
||||
data(){return {
|
||||
showWarning: true,
|
||||
}},
|
||||
meteor: {
|
||||
$subscribe: {
|
||||
'characterList': [],
|
||||
},
|
||||
signedIn(){
|
||||
return Meteor.userId();
|
||||
},
|
||||
userName(){
|
||||
let user = Meteor.user();
|
||||
return user && user.username || user && user._id;
|
||||
},
|
||||
links(){
|
||||
let links = [
|
||||
{title: 'Home', icon: 'home', to: '/'},
|
||||
{title: 'Characters', icon: 'group', to: '/characterList', vif: Meteor.userId()},
|
||||
{title: 'Library', icon: 'book', to: '/library', vif: Meteor.userId()},
|
||||
{title: 'Send Feedback', icon: 'bug_report', to: '/feedback'},
|
||||
{title: 'Patreon', icon: '', href: 'https://www.patreon.com/dicecloud'},
|
||||
{title: 'Github', icon: '', href: 'https://github.com/ThaumRystra/DiceCloud/tree/version-2'},
|
||||
];
|
||||
return links;
|
||||
},
|
||||
signedIn(){
|
||||
return Meteor.userId();
|
||||
},
|
||||
userName(){
|
||||
let user = Meteor.user();
|
||||
return user && user.username || user && user._id;
|
||||
},
|
||||
links(){
|
||||
let isLoggedIn = !!Meteor.userId();
|
||||
let links = [
|
||||
{title: 'Home', icon: 'home', to: '/'},
|
||||
{title: 'Characters', icon: 'portrait', to: '/characterList', requireLogin: true},
|
||||
{title: 'Library', icon: 'book', to: '/library', requireLogin: true},
|
||||
{title: 'Friends', icon: 'people', to: '/friends', requireLogin: true},
|
||||
{title: 'Send Feedback', icon: 'bug_report', to: '/feedback'},
|
||||
{title: 'Patreon', icon: '', href: 'https://www.patreon.com/dicecloud'},
|
||||
{title: 'Github', icon: '', href: 'https://github.com/ThaumRystra/DiceCloud/tree/version-2'},
|
||||
];
|
||||
return links.filter(link => !link.requireLogin || isLoggedIn);
|
||||
},
|
||||
parties(){
|
||||
let parties = Parties.find(
|
||||
{owner: Meteor.userId()},
|
||||
{sort: {name: 1}},
|
||||
).map(party => {
|
||||
const userId = Meteor.userId();
|
||||
return Parties.find(
|
||||
{owner: userId},
|
||||
{sort: {name: 1}},
|
||||
).map(party => {
|
||||
party.characterDocs = Creatures.find(
|
||||
{
|
||||
_id: {$in: party.Creatures},
|
||||
$or: [{readers: userId}, {writers: userId}, {owner: userId}],
|
||||
}, {
|
||||
{
|
||||
_id: {$in: party.Creatures},
|
||||
$or: [{readers: userId}, {writers: userId}, {owner: userId}],
|
||||
}, {
|
||||
sort: {name: 1},
|
||||
fields: {name: 1, urlName: 1},
|
||||
}
|
||||
).map(char => {
|
||||
char.url = `\/character\/${char._id}\/${char.urlName || '-'}`;
|
||||
).map(char => {
|
||||
char.url = `/character/${char._id}/${char.urlName || '-'}`;
|
||||
return char;
|
||||
});
|
||||
return party;
|
||||
});
|
||||
},
|
||||
CreaturesWithNoParty() {
|
||||
var userId = Meteor.userId();
|
||||
var charArrays = Parties.find({owner: userId}).map(p => p.Creatures);
|
||||
var partyChars = _.uniq(_.flatten(charArrays));
|
||||
return Creatures.find(
|
||||
{
|
||||
_id: {$nin: partyChars},
|
||||
$or: [{readers: userId}, {writers: userId}, {owner: userId}],
|
||||
},
|
||||
{sort: {name: 1}}
|
||||
).map(char => {
|
||||
char.url = `\/character\/${char._id}\/${char.urlName || '-'}`;
|
||||
CreaturesWithNoParty() {
|
||||
var userId = Meteor.userId();
|
||||
var charArrays = Parties.find({owner: userId}).map(p => p.Creatures);
|
||||
var partyChars = _.uniq(_.flatten(charArrays));
|
||||
return Creatures.find(
|
||||
{
|
||||
_id: {$nin: partyChars},
|
||||
$or: [{readers: userId}, {writers: userId}, {owner: userId}],
|
||||
},
|
||||
{sort: {name: 1}}
|
||||
).map(char => {
|
||||
char.url = `/character/${char._id}/${char.urlName || '-'}`;
|
||||
return char;
|
||||
});
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,24 +0,0 @@
|
||||
<template>
|
||||
<div>
|
||||
<v-toolbar app color="secondary" dark clipped-left>
|
||||
<v-btn flat icon @click="toggleDrawer">
|
||||
<v-icon>menu</v-icon>
|
||||
</v-btn>
|
||||
<slot name="toolbar"></slot>
|
||||
</v-toolbar>
|
||||
<v-content>
|
||||
<slot></slot>
|
||||
</v-content>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { mapMutations } from "vuex";
|
||||
export default {
|
||||
methods: {
|
||||
...mapMutations([
|
||||
"toggleDrawer",
|
||||
]),
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -1,54 +1,73 @@
|
||||
<template lang="html">
|
||||
<div class="layout row" style="background-color: inherit;">
|
||||
<div
|
||||
class="layout column"
|
||||
style="
|
||||
<div
|
||||
class="layout row"
|
||||
style="background-color: inherit;"
|
||||
>
|
||||
<div
|
||||
class="layout column"
|
||||
style="
|
||||
background-color: inherit;
|
||||
width: initial;
|
||||
max-width: 100%;
|
||||
min-width: 320px;
|
||||
"
|
||||
>
|
||||
<v-toolbar dense flat>
|
||||
<v-spacer/>
|
||||
<v-switch
|
||||
label="Organize"
|
||||
class="mx-3"
|
||||
v-model="organize"
|
||||
style="flex-grow: 0; height: 32px;"
|
||||
/>
|
||||
</v-toolbar>
|
||||
<library-browser
|
||||
edit-mode
|
||||
:organize-mode="organize"
|
||||
:selected-node-id="selected"
|
||||
@selected="e => selected = e"
|
||||
/>
|
||||
</div>
|
||||
<v-divider vertical/>
|
||||
<div style="width: 100%; background-color: inherit;" data-id="selected-node-card">
|
||||
<v-toolbar dense flat>
|
||||
<property-icon :type="selectedNode && selectedNode.type" class="mr-2"/>
|
||||
<div class="title">
|
||||
{{getPropertyName(selectedNode && selectedNode.type)}}
|
||||
</div>
|
||||
<v-spacer/>
|
||||
<v-btn flat icon @click="editLibraryNode" v-if="selectedNode">
|
||||
<v-icon>create</v-icon>
|
||||
</v-btn>
|
||||
</v-toolbar>
|
||||
<v-card-text style="overflow-y: auto;">
|
||||
<property-viewer :model="selectedNode"/>
|
||||
</v-card-text>
|
||||
</div>
|
||||
>
|
||||
<v-toolbar
|
||||
dense
|
||||
flat
|
||||
>
|
||||
<v-spacer />
|
||||
<v-switch
|
||||
v-model="organize"
|
||||
label="Organize"
|
||||
class="mx-3"
|
||||
style="flex-grow: 0; height: 32px;"
|
||||
/>
|
||||
</v-toolbar>
|
||||
<library-browser
|
||||
edit-mode
|
||||
:organize-mode="organize"
|
||||
:selected-node-id="selected"
|
||||
@selected="e => selected = e"
|
||||
/>
|
||||
</div>
|
||||
<v-divider vertical />
|
||||
<div
|
||||
style="width: 100%; background-color: inherit;"
|
||||
data-id="selected-node-card"
|
||||
>
|
||||
<v-toolbar
|
||||
dense
|
||||
flat
|
||||
>
|
||||
<property-icon
|
||||
:type="selectedNode && selectedNode.type"
|
||||
class="mr-2"
|
||||
/>
|
||||
<div class="title">
|
||||
{{ getPropertyName(selectedNode && selectedNode.type) }}
|
||||
</div>
|
||||
<v-spacer />
|
||||
<v-btn
|
||||
v-if="selectedNode"
|
||||
flat
|
||||
icon
|
||||
@click="editLibraryNode"
|
||||
>
|
||||
<v-icon>create</v-icon>
|
||||
</v-btn>
|
||||
</v-toolbar>
|
||||
<v-card-text style="overflow-y: auto;">
|
||||
<property-viewer :model="selectedNode" />
|
||||
</v-card-text>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ToolbarLayout from '/imports/ui/layouts/ToolbarLayout.vue';
|
||||
import LibraryBrowser from '/imports/ui/library/LibraryBrowser.vue';
|
||||
import PropertyViewer from '/imports/ui/properties/shared/PropertyViewer.vue';
|
||||
import LibraryNodes, { insertNode } from '/imports/api/library/LibraryNodes.js';
|
||||
import LibraryNodes from '/imports/api/library/LibraryNodes.js';
|
||||
import Libraries from '/imports/api/library/Libraries.js';
|
||||
import PropertyIcon from '/imports/ui/properties/shared/PropertyIcon.vue';
|
||||
import { getPropertyName } from '/imports/constants/PROPERTIES.js';
|
||||
@@ -56,7 +75,6 @@ import { getPropertyName } from '/imports/constants/PROPERTIES.js';
|
||||
export default {
|
||||
components: {
|
||||
LibraryBrowser,
|
||||
ToolbarLayout,
|
||||
PropertyViewer,
|
||||
PropertyIcon,
|
||||
},
|
||||
|
||||
@@ -1,163 +1,154 @@
|
||||
<template>
|
||||
<toolbar-layout>
|
||||
<span slot="toolbar">
|
||||
Account
|
||||
</span>
|
||||
<v-layout
|
||||
align-center
|
||||
justify-center
|
||||
>
|
||||
<v-card class="ma-4 pa-2">
|
||||
<v-list>
|
||||
<v-list-tile>
|
||||
<v-switch
|
||||
:input-value="darkMode"
|
||||
label="Dark mode"
|
||||
@change="setDarkMode"
|
||||
/>
|
||||
</v-list-tile>
|
||||
<v-subheader>
|
||||
Username
|
||||
</v-subheader>
|
||||
<v-list-tile>
|
||||
<v-list-tile-title>
|
||||
{{ user && user.username }}
|
||||
</v-list-tile-title>
|
||||
<v-list-tile-action>
|
||||
<v-tooltip left>
|
||||
<span>Change Username</span>
|
||||
<v-btn
|
||||
slot="activator"
|
||||
icon
|
||||
flat
|
||||
>
|
||||
<v-icon>create</v-icon>
|
||||
</v-btn>
|
||||
</v-tooltip>
|
||||
</v-list-tile-action>
|
||||
</v-list-tile>
|
||||
<v-subheader>
|
||||
Email
|
||||
</v-subheader>
|
||||
<v-list-tile
|
||||
v-for="email in emails"
|
||||
:key="email.address"
|
||||
>
|
||||
<v-list-tile-title>
|
||||
{{ email.address }}
|
||||
</v-list-tile-title>
|
||||
<v-list-tile-action>
|
||||
<v-tooltip
|
||||
v-if="email.verified"
|
||||
left
|
||||
>
|
||||
<span>Verified</span>
|
||||
<v-icon slot="activator">
|
||||
assignment_turned_in
|
||||
</v-icon>
|
||||
</v-tooltip>
|
||||
<v-tooltip left>
|
||||
<span>Verify Account</span>
|
||||
<v-btn
|
||||
slot="activator"
|
||||
flat
|
||||
icon
|
||||
@click="verifyEmail(email.address)"
|
||||
>
|
||||
<v-icon>assignment_late</v-icon>
|
||||
</v-btn>
|
||||
</v-tooltip>
|
||||
</v-list-tile-action>
|
||||
</v-list-tile>
|
||||
<v-list-tile>
|
||||
<v-list-tile-action>
|
||||
<v-tooltip right>
|
||||
<span>Add email address</span>
|
||||
<v-btn
|
||||
slot="activator"
|
||||
flat
|
||||
icon
|
||||
>
|
||||
<v-icon>add</v-icon>
|
||||
</v-btn>
|
||||
</v-tooltip>
|
||||
</v-list-tile-action>
|
||||
</v-list-tile>
|
||||
<v-subheader>
|
||||
API Key
|
||||
</v-subheader>
|
||||
<v-list-tile v-if="user && user.apiKey">
|
||||
<v-list-tile v-if="showApiKey">
|
||||
{{ user.apiKey }}
|
||||
</v-list-tile>
|
||||
<v-list-tile-title>
|
||||
{{ "•".repeat(user.apiKey.length) }}
|
||||
</v-list-tile-title>
|
||||
<v-list-tile-action>
|
||||
<div>
|
||||
<v-card class="ma-4 pa-2">
|
||||
<v-list>
|
||||
<v-list-tile>
|
||||
<v-switch
|
||||
:input-value="darkMode"
|
||||
label="Dark mode"
|
||||
@change="setDarkMode"
|
||||
/>
|
||||
</v-list-tile>
|
||||
<v-subheader>
|
||||
Username
|
||||
</v-subheader>
|
||||
<v-list-tile>
|
||||
<v-list-tile-title>
|
||||
{{ user && user.username }}
|
||||
</v-list-tile-title>
|
||||
<v-list-tile-action>
|
||||
<v-tooltip left>
|
||||
<span>Change Username</span>
|
||||
<v-btn
|
||||
slot="activator"
|
||||
icon
|
||||
flat
|
||||
>
|
||||
<v-icon>create</v-icon>
|
||||
</v-btn>
|
||||
</v-tooltip>
|
||||
</v-list-tile-action>
|
||||
</v-list-tile>
|
||||
<v-subheader>
|
||||
Email
|
||||
</v-subheader>
|
||||
<v-list-tile
|
||||
v-for="email in emails"
|
||||
:key="email.address"
|
||||
>
|
||||
<v-list-tile-title>
|
||||
{{ email.address }}
|
||||
</v-list-tile-title>
|
||||
<v-list-tile-action>
|
||||
<v-tooltip
|
||||
v-if="email.verified"
|
||||
left
|
||||
>
|
||||
<span>Verified</span>
|
||||
<v-icon slot="activator">
|
||||
assignment_turned_in
|
||||
</v-icon>
|
||||
</v-tooltip>
|
||||
<v-tooltip left>
|
||||
<span>Verify Account</span>
|
||||
<v-btn
|
||||
slot="activator"
|
||||
flat
|
||||
icon
|
||||
@click="showApiKey=!showApiKey"
|
||||
@click="verifyEmail(email.address)"
|
||||
>
|
||||
<v-icon>{{ showApiKey ? 'visibility_off' : 'visibility' }}</v-icon>
|
||||
<v-icon>assignment_late</v-icon>
|
||||
</v-btn>
|
||||
</v-list-tile-action>
|
||||
</v-tooltip>
|
||||
</v-list-tile-action>
|
||||
</v-list-tile>
|
||||
<v-list-tile>
|
||||
<v-list-tile-action>
|
||||
<v-tooltip right>
|
||||
<span>Add email address</span>
|
||||
<v-btn
|
||||
slot="activator"
|
||||
flat
|
||||
icon
|
||||
>
|
||||
<v-icon>add</v-icon>
|
||||
</v-btn>
|
||||
</v-tooltip>
|
||||
</v-list-tile-action>
|
||||
</v-list-tile>
|
||||
<v-subheader>
|
||||
API Key
|
||||
</v-subheader>
|
||||
<v-list-tile v-if="user && user.apiKey">
|
||||
<v-list-tile v-if="showApiKey">
|
||||
{{ user.apiKey }}
|
||||
</v-list-tile>
|
||||
<v-list-tile v-else>
|
||||
<v-list-tile-title>
|
||||
{{ "•".repeat(user.apiKey.length) }}
|
||||
</v-list-tile-title>
|
||||
<v-list-tile-action>
|
||||
<v-btn
|
||||
flat
|
||||
color="accent"
|
||||
@click="generateKey"
|
||||
icon
|
||||
@click="showApiKey=!showApiKey"
|
||||
>
|
||||
Generate API Key
|
||||
<v-icon>{{ showApiKey ? 'visibility_off' : 'visibility' }}</v-icon>
|
||||
</v-btn>
|
||||
</v-list-tile>
|
||||
<!--
|
||||
<v-subheader>
|
||||
Google Account
|
||||
</v-subheader>
|
||||
<v-list-tile v-if="googleAccount">
|
||||
<v-list-tile-avatar>
|
||||
<img src="googleAccount.picture">
|
||||
</v-list-tile-avatar>
|
||||
<v-list-tile-content>
|
||||
<v-list-tile-title>
|
||||
{{ googleAccount.name }}
|
||||
</v-list-tile-title>
|
||||
<v-list-tile-sub-title>
|
||||
{{ googleAccount.email }}
|
||||
</v-list-tile-sub-title>
|
||||
</v-list-tile-content>
|
||||
</v-list-tile>
|
||||
<v-list-tile v-else="googleAccount">
|
||||
<v-btn
|
||||
flat
|
||||
color="accent"
|
||||
>
|
||||
Connect Google
|
||||
</v-btn>
|
||||
</v-list-tile>
|
||||
-->
|
||||
</v-list>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
</v-list-tile-action>
|
||||
</v-list-tile>
|
||||
<v-list-tile v-else>
|
||||
<v-btn
|
||||
flat
|
||||
color="accent"
|
||||
@click="signOut"
|
||||
@click="generateKey"
|
||||
>
|
||||
Sign Out
|
||||
Generate API Key
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</v-layout>
|
||||
</toolbar-layout>
|
||||
</v-list-tile>
|
||||
<!--
|
||||
<v-subheader>
|
||||
Google Account
|
||||
</v-subheader>
|
||||
<v-list-tile v-if="googleAccount">
|
||||
<v-list-tile-avatar>
|
||||
<img src="googleAccount.picture">
|
||||
</v-list-tile-avatar>
|
||||
<v-list-tile-content>
|
||||
<v-list-tile-title>
|
||||
{{ googleAccount.name }}
|
||||
</v-list-tile-title>
|
||||
<v-list-tile-sub-title>
|
||||
{{ googleAccount.email }}
|
||||
</v-list-tile-sub-title>
|
||||
</v-list-tile-content>
|
||||
</v-list-tile>
|
||||
<v-list-tile v-else="googleAccount">
|
||||
<v-btn
|
||||
flat
|
||||
color="accent"
|
||||
>
|
||||
Connect Google
|
||||
</v-btn>
|
||||
</v-list-tile>
|
||||
-->
|
||||
</v-list>
|
||||
<v-card-actions>
|
||||
<v-spacer />
|
||||
<v-btn
|
||||
flat
|
||||
color="accent"
|
||||
@click="signOut"
|
||||
>
|
||||
Sign Out
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import router from '/imports/ui/router.js';
|
||||
import ToolbarLayout from '/imports/ui/layouts/ToolbarLayout.vue';
|
||||
|
||||
|
||||
export default {
|
||||
meteor: {
|
||||
$subscribe: {
|
||||
@@ -178,9 +169,6 @@
|
||||
return this.user && this.user.darkMode;
|
||||
},
|
||||
},
|
||||
components: {
|
||||
ToolbarLayout,
|
||||
},
|
||||
data(){ return {
|
||||
showApiKey: false,
|
||||
signOutBusy: false,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
<template>
|
||||
<toolbar-layout>
|
||||
<span slot="toolbar">Characters</span>
|
||||
<div>
|
||||
<v-card class="ma-4">
|
||||
<v-list v-if="CreaturesWithNoParty.length">
|
||||
<v-list-tile
|
||||
@@ -9,21 +8,21 @@
|
||||
:to="character.url"
|
||||
>
|
||||
<v-list-tile-avatar :color="character.color">
|
||||
<img
|
||||
<img
|
||||
v-if="character.picture"
|
||||
:src="character.picture"
|
||||
alt="character.name"
|
||||
>
|
||||
<template v-else>
|
||||
{{character.initial}}
|
||||
</template>
|
||||
>
|
||||
<template v-else>
|
||||
{{ character.initial }}
|
||||
</template>
|
||||
</v-list-tile-avatar>
|
||||
<v-list-tile-content>
|
||||
<v-list-tile-title>
|
||||
{{character.name}}
|
||||
{{ character.name }}
|
||||
</v-list-tile-title>
|
||||
<v-list-tile-sub-title>
|
||||
{{character.alignment}} {{character.gender}} {{character.race}}
|
||||
{{ character.alignment }} {{ character.gender }} {{ character.race }}
|
||||
</v-list-tile-sub-title>
|
||||
</v-list-tile-content>
|
||||
</v-list-tile>
|
||||
@@ -33,7 +32,9 @@
|
||||
v-for="party in parties"
|
||||
:key="party._id"
|
||||
>
|
||||
<div slot="header">{{party.name}}</div>
|
||||
<div slot="header">
|
||||
{{ party.name }}
|
||||
</div>
|
||||
<v-card>
|
||||
<v-list>
|
||||
<v-list-tile
|
||||
@@ -41,7 +42,10 @@
|
||||
:key="character._id"
|
||||
>
|
||||
<v-list-tile-avatar>
|
||||
<img :src="character.picture" alt="character.name">
|
||||
<img
|
||||
:src="character.picture"
|
||||
alt="character.name"
|
||||
>
|
||||
</v-list-tile-avatar>
|
||||
</v-list-tile>
|
||||
</v-list>
|
||||
@@ -50,104 +54,109 @@
|
||||
</v-expansion-panel>
|
||||
</v-card>
|
||||
<v-speed-dial
|
||||
v-model="fab"
|
||||
fixed
|
||||
bottom
|
||||
right
|
||||
transition="slide-y-reverse-transition"
|
||||
v-model="fab"
|
||||
>
|
||||
<v-btn
|
||||
slot="activator"
|
||||
v-model="fab"
|
||||
color="accent"
|
||||
fab
|
||||
v-model="fab"
|
||||
>
|
||||
<v-icon>add</v-icon>
|
||||
<v-icon>close</v-icon>
|
||||
</v-btn>
|
||||
<labeled-fab icon="face" label="New Character" @click="insertCharacter"></labeled-fab>
|
||||
<labeled-fab icon="group" label="New Party"></labeled-fab>
|
||||
<labeled-fab
|
||||
icon="face"
|
||||
label="New Character"
|
||||
@click="insertCharacter"
|
||||
/>
|
||||
<labeled-fab
|
||||
icon="group"
|
||||
label="New Party"
|
||||
/>
|
||||
</v-speed-dial>
|
||||
</toolbar-layout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Creatures, {insertCreature} from '/imports/api/creature/Creatures.js';
|
||||
import Parties from '/imports/api/campaign/Parties.js';
|
||||
import store from "/imports/ui/vuexStore.js";
|
||||
import ToolbarLayout from "/imports/ui/layouts/ToolbarLayout.vue";
|
||||
import LabeledFab from "/imports/ui/components/LabeledFab.vue";
|
||||
import CharacterCreationDialog from "/imports/ui/creature/character/CharacterCreationDialog.vue";
|
||||
import Creatures, {insertCreature} from '/imports/api/creature/Creatures.js';
|
||||
import Parties from '/imports/api/campaign/Parties.js';
|
||||
import LabeledFab from '/imports/ui/components/LabeledFab.vue';
|
||||
|
||||
const characterTransform = function(char){
|
||||
char.url = `\/character\/${char._id}\/${char.urlName || "-"}`;
|
||||
char.initial = char.name && char.name[0] || "?";
|
||||
char.url = `/character/${char._id}/${char.urlName || '-'}`;
|
||||
char.initial = char.name && char.name[0] || '?';
|
||||
return char;
|
||||
};
|
||||
export default {
|
||||
components: {
|
||||
LabeledFab,
|
||||
},
|
||||
data(){ return{
|
||||
fab: false,
|
||||
}},
|
||||
meteor: {
|
||||
$subscribe: {
|
||||
"characterList": [],
|
||||
'characterList': [],
|
||||
},
|
||||
parties(){
|
||||
const userId = Meteor.userId();
|
||||
let parties = Parties.find(
|
||||
{owner: Meteor.userId()},
|
||||
{sort: {name: 1}},
|
||||
).map(party => {
|
||||
{owner: userId},
|
||||
{sort: {name: 1}},
|
||||
).map(party => {
|
||||
party.characterDocs = Creatures.find(
|
||||
{
|
||||
_id: {$in: party.Creatures},
|
||||
$or: [{readers: userId}, {writers: userId}, {owner: userId}],
|
||||
}, {
|
||||
{
|
||||
_id: {$in: party.Creatures},
|
||||
$or: [{readers: userId}, {writers: userId}, {owner: userId}],
|
||||
}, {
|
||||
sort: {name: 1},
|
||||
}
|
||||
).map(characterTransform);
|
||||
).map(characterTransform);
|
||||
return party;
|
||||
});
|
||||
return parties;
|
||||
},
|
||||
CreaturesWithNoParty() {
|
||||
var userId = Meteor.userId();
|
||||
var charArrays = Parties.find({owner: userId}).map(p => p.Creatures);
|
||||
var partyChars = _.uniq(_.flatten(charArrays));
|
||||
return Creatures.find(
|
||||
{
|
||||
_id: {$nin: partyChars},
|
||||
$or: [{readers: userId}, {writers: userId}, {owner: userId}],
|
||||
},
|
||||
{sort: {name: 1}}
|
||||
).map(characterTransform);
|
||||
},
|
||||
var userId = Meteor.userId();
|
||||
var charArrays = Parties.find({owner: userId}).map(p => p.Creatures);
|
||||
var partyChars = _.uniq(_.flatten(charArrays));
|
||||
return Creatures.find(
|
||||
{
|
||||
_id: {$nin: partyChars},
|
||||
$or: [{readers: userId}, {writers: userId}, {owner: userId}],
|
||||
},
|
||||
{sort: {name: 1}}
|
||||
).map(characterTransform);
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
insertCharacter(){
|
||||
insertCreature.call((error, result) => {
|
||||
if (error){
|
||||
console.error(error);
|
||||
} else {
|
||||
this.$router.push({ path: `/character/${result}`})
|
||||
}
|
||||
});
|
||||
insertCreature.call((error, result) => {
|
||||
if (error){
|
||||
console.error(error);
|
||||
} else {
|
||||
this.$router.push({ path: `/character/${result}`})
|
||||
}
|
||||
});
|
||||
|
||||
/*
|
||||
store.commit("pushDialogStack", {
|
||||
store.commit("pushDialogStack", {
|
||||
component: CharacterCreationDialog,
|
||||
data: {},
|
||||
element: undefined,
|
||||
returnElement: undefined,
|
||||
callback(result){
|
||||
if (!result) return;
|
||||
if (!result) return;
|
||||
insertCreature.call(result);
|
||||
},
|
||||
});
|
||||
*/
|
||||
*/
|
||||
},
|
||||
},
|
||||
components: {
|
||||
ToolbarLayout,
|
||||
LabeledFab,
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,5 +1,9 @@
|
||||
<template>
|
||||
<character-sheet show-menu-button :creature-id="$route.params.id" />
|
||||
<character-sheet
|
||||
show-menu-button
|
||||
:creature-id="$route.params.id"
|
||||
:tabs="tabs"
|
||||
/>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -8,5 +12,11 @@ export default {
|
||||
components: {
|
||||
CharacterSheet,
|
||||
},
|
||||
props: {
|
||||
tabs: {
|
||||
type: Number,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
}
|
||||
</script>
|
||||
|
||||
20
app/imports/ui/pages/Friends.vue
Normal file
20
app/imports/ui/pages/Friends.vue
Normal file
@@ -0,0 +1,20 @@
|
||||
<template>
|
||||
<div>
|
||||
<div slot="toolbar">
|
||||
Friends
|
||||
</div>
|
||||
<v-sheet>
|
||||
<h1>
|
||||
Friends
|
||||
</h1>
|
||||
<v-btn
|
||||
fixed
|
||||
bottom
|
||||
right
|
||||
fab
|
||||
>
|
||||
<v-icon>add</v-icon>
|
||||
</v-btn>
|
||||
</v-sheet>
|
||||
</div>
|
||||
</template>
|
||||
@@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<toolbar-layout>
|
||||
<div slot="toolbar">
|
||||
DiceCloud
|
||||
</div>
|
||||
<div>
|
||||
<div class="content">
|
||||
<section>
|
||||
<v-parallax
|
||||
@@ -195,15 +192,11 @@
|
||||
</v-layout>
|
||||
</section>
|
||||
</div>
|
||||
</toolbar-layout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ToolbarLayout from '/imports/ui/layouts/ToolbarLayout.vue';
|
||||
export default {
|
||||
components: {
|
||||
ToolbarLayout,
|
||||
},
|
||||
meteor: {
|
||||
signedIn(){
|
||||
return Meteor.userId();
|
||||
|
||||
@@ -1,20 +1,15 @@
|
||||
<template lang="html">
|
||||
<toolbar-layout>
|
||||
<template slot="toolbar">
|
||||
Libraries
|
||||
</template>
|
||||
<v-card class="ma-4">
|
||||
<library-and-node/>
|
||||
</v-card>
|
||||
</toolbar-layout>
|
||||
<div>
|
||||
<v-card class="ma-4">
|
||||
<library-and-node />
|
||||
</v-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ToolbarLayout from '/imports/ui/layouts/ToolbarLayout.vue';
|
||||
import LibraryAndNode from '/imports/ui/library/LibraryAndNode.vue';
|
||||
export default {
|
||||
components: {
|
||||
ToolbarLayout,
|
||||
LibraryAndNode,
|
||||
},
|
||||
};
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<toolbar-layout>
|
||||
<div slot="toolbar">
|
||||
Not Found
|
||||
</div>
|
||||
<div>
|
||||
<v-layout
|
||||
align-center
|
||||
justify-center
|
||||
@@ -11,14 +8,5 @@
|
||||
No page was found for this address
|
||||
</h1>
|
||||
</v-layout>
|
||||
</toolbar-layout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ToolbarLayout from '/imports/ui/layouts/ToolbarLayout.vue';
|
||||
export default {
|
||||
components: {
|
||||
ToolbarLayout,
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,22 +1,10 @@
|
||||
<template lang="html">
|
||||
<toolbar-layout>
|
||||
<div slot="toolbar">
|
||||
Not yet implemented
|
||||
</div>
|
||||
<v-alert
|
||||
:value="true"
|
||||
type="info"
|
||||
>
|
||||
This page is not available in this version of the alpha.
|
||||
</v-alert>
|
||||
</toolbar-layout>
|
||||
<div>
|
||||
<v-alert
|
||||
:value="true"
|
||||
type="info"
|
||||
>
|
||||
This page is not available in this version of the alpha.
|
||||
</v-alert>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ToolbarLayout from '/imports/ui/layouts/ToolbarLayout.vue';
|
||||
export default {
|
||||
components: {
|
||||
ToolbarLayout,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<toolbar-layout>
|
||||
<div slot="toolbar">
|
||||
Patreon tier not high enough
|
||||
</div>
|
||||
<div>
|
||||
<v-layout
|
||||
column
|
||||
align-center
|
||||
@@ -15,16 +12,11 @@
|
||||
You need to pledge at least $5 to use this beta.
|
||||
</h2>
|
||||
</v-layout>
|
||||
</toolbar-layout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ToolbarLayout from '/imports/ui/layouts/ToolbarLayout.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
ToolbarLayout,
|
||||
},
|
||||
meteor: {
|
||||
entitledDollars(){
|
||||
let user = Meteor.user();
|
||||
|
||||
@@ -1,123 +1,134 @@
|
||||
<template>
|
||||
<ToolbarLayout>
|
||||
<div slot="toolbar">Sign Up</div>
|
||||
<v-form ref="form" class="mt-4">
|
||||
<v-layout column align-center>
|
||||
<v-img
|
||||
src="crown-dice-logo-cropped-transparent.png"
|
||||
width="120px"
|
||||
class="ma-3"></v-img>
|
||||
<v-text-field
|
||||
type="text"
|
||||
label="Email"
|
||||
v-model="email"
|
||||
:rules="emailRules"
|
||||
@keyup.enter="submit"
|
||||
required
|
||||
></v-text-field>
|
||||
<v-text-field
|
||||
type="text"
|
||||
label="Username"
|
||||
v-model="username"
|
||||
:rules="usernameRules"
|
||||
@keyup.enter="submit"
|
||||
required
|
||||
></v-text-field>
|
||||
<v-text-field
|
||||
type="password"
|
||||
label="Password"
|
||||
v-model="password"
|
||||
:rules="passwordRules"
|
||||
@keyup.enter="submit"
|
||||
required
|
||||
></v-text-field>
|
||||
<v-text-field
|
||||
type="password"
|
||||
label="Password Again"
|
||||
v-model="password2"
|
||||
:rules="password2Rules"
|
||||
@keyup.enter="submit"
|
||||
required
|
||||
></v-text-field>
|
||||
<div class="error--text">
|
||||
{{error}}
|
||||
</div>
|
||||
<v-layout row>
|
||||
<v-btn
|
||||
:disabled="!valid"
|
||||
@click="submit"
|
||||
color="accent"
|
||||
>
|
||||
Register
|
||||
</v-btn>
|
||||
</v-layout>
|
||||
</v-layout>
|
||||
</v-form>
|
||||
<v-divider class="ma-4"></v-divider>
|
||||
<v-layout column align-center>
|
||||
<div class="error--text">
|
||||
{{googleError}}
|
||||
</div>
|
||||
<v-btn color="accent" @click="googleLogin">
|
||||
Register in with Google
|
||||
</v-btn>
|
||||
</v-layout>
|
||||
</ToolbarLayout>
|
||||
<div>
|
||||
<div slot="toolbar">
|
||||
Sign Up
|
||||
</div>
|
||||
<v-form
|
||||
ref="form"
|
||||
class="mt-4"
|
||||
>
|
||||
<v-layout
|
||||
column
|
||||
align-center
|
||||
>
|
||||
<v-img
|
||||
src="crown-dice-logo-cropped-transparent.png"
|
||||
width="120px"
|
||||
class="ma-3"
|
||||
/>
|
||||
<v-text-field
|
||||
v-model="email"
|
||||
type="text"
|
||||
label="Email"
|
||||
:rules="emailRules"
|
||||
required
|
||||
@keyup.enter="submit"
|
||||
/>
|
||||
<v-text-field
|
||||
v-model="username"
|
||||
type="text"
|
||||
label="Username"
|
||||
:rules="usernameRules"
|
||||
required
|
||||
@keyup.enter="submit"
|
||||
/>
|
||||
<v-text-field
|
||||
v-model="password"
|
||||
type="password"
|
||||
label="Password"
|
||||
:rules="passwordRules"
|
||||
required
|
||||
@keyup.enter="submit"
|
||||
/>
|
||||
<v-text-field
|
||||
v-model="password2"
|
||||
type="password"
|
||||
label="Password Again"
|
||||
:rules="password2Rules"
|
||||
required
|
||||
@keyup.enter="submit"
|
||||
/>
|
||||
<div class="error--text">
|
||||
{{ error }}
|
||||
</div>
|
||||
<v-layout row>
|
||||
<v-btn
|
||||
:disabled="!valid"
|
||||
color="accent"
|
||||
@click="submit"
|
||||
>
|
||||
Register
|
||||
</v-btn>
|
||||
</v-layout>
|
||||
</v-layout>
|
||||
</v-form>
|
||||
<v-divider class="ma-4" />
|
||||
<v-layout
|
||||
column
|
||||
align-center
|
||||
>
|
||||
<div class="error--text">
|
||||
{{ googleError }}
|
||||
</div>
|
||||
<v-btn
|
||||
color="accent"
|
||||
@click="googleLogin"
|
||||
>
|
||||
Register in with Google
|
||||
</v-btn>
|
||||
</v-layout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import ToolbarLayout from "/imports/ui/layouts/ToolbarLayout.vue";
|
||||
import router from "/imports/ui/router.js";
|
||||
export default{
|
||||
data() {
|
||||
return {
|
||||
valid: true,
|
||||
username: "",
|
||||
usernameRules: [
|
||||
v => !!v || "Name is required",
|
||||
],
|
||||
email: "",
|
||||
emailRules: [
|
||||
v => !!v || "Name is required",
|
||||
v => /.+@.+/.test(v) || 'E-mail must be valid',
|
||||
],
|
||||
password: "",
|
||||
passwordRules: [
|
||||
v => !!v || "Password is required",
|
||||
],
|
||||
password2: "",
|
||||
password2Rules: [
|
||||
v => !!v || "Password is required",
|
||||
v => v == this.password || "Passwords don't match",
|
||||
],
|
||||
error: "",
|
||||
googleError: "",
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
import router from '/imports/ui/router.js';
|
||||
export default{
|
||||
data() {
|
||||
return {
|
||||
valid: true,
|
||||
username: '',
|
||||
usernameRules: [
|
||||
v => !!v || 'Name is required',
|
||||
],
|
||||
email: '',
|
||||
emailRules: [
|
||||
v => !!v || 'Name is required',
|
||||
v => /.+@.+/.test(v) || 'E-mail must be valid',
|
||||
],
|
||||
password: '',
|
||||
passwordRules: [
|
||||
v => !!v || 'Password is required',
|
||||
],
|
||||
password2: '',
|
||||
password2Rules: [
|
||||
v => !!v || 'Password is required',
|
||||
v => v == this.password || 'Passwords don\'t match',
|
||||
],
|
||||
error: '',
|
||||
googleError: '',
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
submit () {
|
||||
if (this.$refs.form.validate()) {
|
||||
Accounts.createUser({
|
||||
username: this.username,
|
||||
password: this.password,
|
||||
email: this.email,
|
||||
}, error => {
|
||||
if (error){
|
||||
this.error = error.reason;
|
||||
} else {
|
||||
router.push("characterList");
|
||||
}
|
||||
});
|
||||
Accounts.createUser({
|
||||
username: this.username,
|
||||
password: this.password,
|
||||
email: this.email,
|
||||
}, error => {
|
||||
if (error){
|
||||
this.error = error.reason;
|
||||
} else {
|
||||
router.push('characterList');
|
||||
}
|
||||
});
|
||||
}
|
||||
},
|
||||
googleLogin() {
|
||||
Meteor.loginWithGoogle(error => {
|
||||
if (error) this.googleError = error.reason;
|
||||
});
|
||||
},
|
||||
googleLogin() {
|
||||
Meteor.loginWithGoogle(error => {
|
||||
if (error) this.googleError = error.reason;
|
||||
});
|
||||
},
|
||||
},
|
||||
components: {
|
||||
ToolbarLayout,
|
||||
},
|
||||
}
|
||||
}
|
||||
</script>
|
||||
|
||||
@@ -1,8 +1,5 @@
|
||||
<template>
|
||||
<ToolbarLayout>
|
||||
<div slot="toolbar">
|
||||
Sign In
|
||||
</div>
|
||||
<div>
|
||||
<v-form
|
||||
ref="form"
|
||||
class="mt-4"
|
||||
@@ -83,17 +80,13 @@
|
||||
Sign in with Patreon
|
||||
</v-btn>
|
||||
</v-layout>
|
||||
</ToolbarLayout>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import { Meteor } from 'meteor/meteor'
|
||||
import ToolbarLayout from '/imports/ui/layouts/ToolbarLayout.vue';
|
||||
import router from '/imports/ui/router.js';
|
||||
export default{
|
||||
components: {
|
||||
ToolbarLayout,
|
||||
},
|
||||
data: () => ({
|
||||
valid: true,
|
||||
name: '',
|
||||
|
||||
@@ -1,40 +1,62 @@
|
||||
import { RouterFactory, nativeScrollBehavior } from 'meteor/akryum:vue-router2';
|
||||
import { getEntitledCentsOfUser } from '/imports/api/users/Users.js';
|
||||
|
||||
// Components
|
||||
import Home from '/imports/ui/pages/Home.vue';
|
||||
import CharacterList from '/imports/ui/pages/CharacterList.vue';
|
||||
import Library from '/imports/ui/pages/Library.vue';
|
||||
import CharacterSheetPage from '/imports/ui/pages/CharacterSheetPage.vue';
|
||||
import CharacterSheetToolbarItems from '/imports/ui/creature/character/CharacterSheetToolbarItems.vue';
|
||||
import CharacterSheetToolbarExtension from '/imports/ui/creature/character/CharacterSheetToolbarExtension.vue';
|
||||
import SignIn from '/imports/ui/pages/SignIn.vue' ;
|
||||
import Register from '/imports/ui/pages/Register.vue' ;
|
||||
import Register from '/imports/ui/pages/Register.vue';
|
||||
import Friends from '/imports/ui/pages/Friends.vue' ;
|
||||
import Account from '/imports/ui/pages/Account.vue' ;
|
||||
import NotImplemented from '/imports/ui/pages/NotImplemented.vue';
|
||||
import PatreonLevelTooLow from '/imports/ui/pages/PatreonLevelTooLow.vue';
|
||||
|
||||
let userSubscription = Meteor.subscribe('user');
|
||||
|
||||
// Not found
|
||||
import NotFound from '/imports/ui/pages/NotFound.vue';
|
||||
|
||||
|
||||
// Create router instance
|
||||
const routerFactory = new RouterFactory({
|
||||
mode: 'history',
|
||||
scrollBehavior: nativeScrollBehavior,
|
||||
});
|
||||
|
||||
function ensurePatronTier(to, from, next){
|
||||
let user = Meteor.user();
|
||||
if (!user){
|
||||
next('/sign-in');
|
||||
return;
|
||||
}
|
||||
let entitledCents = user.services.patreon.entitledCents || 0;
|
||||
let overrideCents = user.services.patreon.entitledCentsOverride || 0;
|
||||
|
||||
if (entitledCents < 500 && overrideCents < 500){
|
||||
next('/patreon-level-too-low');
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
function ensureLoggedIn(to, from, next){
|
||||
Tracker.autorun((computation) => {
|
||||
if (userSubscription.ready()){
|
||||
computation.stop();
|
||||
const user = Meteor.user();
|
||||
if (user){
|
||||
next()
|
||||
} else {
|
||||
next('/sign-in');
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
function ensurePatronTier5(to, from, next){
|
||||
Tracker.autorun((computation) => {
|
||||
if (userSubscription.ready()){
|
||||
computation.stop();
|
||||
const user = Meteor.user();
|
||||
if (!user){
|
||||
next('/sign-in');
|
||||
return;
|
||||
}
|
||||
let entitledCents = getEntitledCentsOfUser(user);
|
||||
if (entitledCents < 500){
|
||||
next('/patreon-level-too-low');
|
||||
} else {
|
||||
next();
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
RouterFactory.configure(factory => {
|
||||
@@ -42,38 +64,101 @@ RouterFactory.configure(factory => {
|
||||
{
|
||||
path: '/',
|
||||
name: 'home',
|
||||
component: Home,
|
||||
components: {
|
||||
default: Home,
|
||||
},
|
||||
meta: {
|
||||
title: 'Home',
|
||||
},
|
||||
},{
|
||||
path: '/characterList',
|
||||
component: CharacterList,
|
||||
beforeEnter: ensurePatronTier,
|
||||
components: {
|
||||
default: CharacterList,
|
||||
},
|
||||
meta: {
|
||||
title: 'Character List',
|
||||
},
|
||||
beforeEnter: ensurePatronTier5,
|
||||
},{
|
||||
path: '/library',
|
||||
component: Library,
|
||||
beforeEnter: ensurePatronTier,
|
||||
components: {
|
||||
default: Library,
|
||||
},
|
||||
meta: {
|
||||
title: 'Library',
|
||||
},
|
||||
beforeEnter: ensurePatronTier5,
|
||||
},{
|
||||
path: '/character/:id/:urlName',
|
||||
component: CharacterSheetPage,
|
||||
beforeEnter: ensurePatronTier,
|
||||
components: {
|
||||
default: CharacterSheetPage,
|
||||
toolbarExtension: CharacterSheetToolbarExtension,
|
||||
toolbarItems: CharacterSheetToolbarItems,
|
||||
},
|
||||
meta: {
|
||||
title: 'Character Sheet',
|
||||
},
|
||||
beforeEnter: ensurePatronTier5,
|
||||
},{
|
||||
path: '/character/:id',
|
||||
component: CharacterSheetPage,
|
||||
beforeEnter: ensurePatronTier,
|
||||
components: {
|
||||
default: CharacterSheetPage,
|
||||
toolbarExtension: CharacterSheetToolbarExtension,
|
||||
toolbarItems: CharacterSheetToolbarItems,
|
||||
},
|
||||
meta: {
|
||||
title: 'Character Sheet',
|
||||
},
|
||||
beforeEnter: ensurePatronTier5,
|
||||
},{
|
||||
path: '/friends',
|
||||
components: {
|
||||
default: Friends,
|
||||
},
|
||||
meta: {
|
||||
title: 'Friends',
|
||||
},
|
||||
beforeEnter: ensureLoggedIn,
|
||||
},{
|
||||
path: '/sign-in',
|
||||
component: SignIn,
|
||||
components: {
|
||||
default: SignIn,
|
||||
},
|
||||
meta: {
|
||||
title: 'Sign In',
|
||||
},
|
||||
},/*{
|
||||
path: '/register',
|
||||
component: Register,
|
||||
components: {
|
||||
default: Register,
|
||||
},
|
||||
meta: {
|
||||
title: 'Home',
|
||||
},
|
||||
},*/{
|
||||
path: '/account',
|
||||
component: Account,
|
||||
components: {
|
||||
default: Account,
|
||||
},
|
||||
meta: {
|
||||
title: 'Account',
|
||||
},
|
||||
},{
|
||||
path: '/feedback',
|
||||
component: NotImplemented,
|
||||
components: {
|
||||
default: NotImplemented,
|
||||
},
|
||||
meta: {
|
||||
title: 'Feedback',
|
||||
},
|
||||
},{
|
||||
path: '/patreon-level-too-low',
|
||||
component: PatreonLevelTooLow,
|
||||
components: {
|
||||
default: PatreonLevelTooLow,
|
||||
},
|
||||
meta: {
|
||||
title: 'Patreon Tier Too Low',
|
||||
},
|
||||
},
|
||||
]);
|
||||
// Icon admin routes
|
||||
|
||||
@@ -1,6 +1,6 @@
|
||||
import Vue from "vue";
|
||||
import Vuex from "vuex";
|
||||
import dialogStackStore from "/imports/ui/dialogStack/dialogStackStore.js";
|
||||
import Vue from 'vue';
|
||||
import Vuex from 'vuex';
|
||||
import dialogStackStore from '/imports/ui/dialogStack/dialogStackStore.js';
|
||||
|
||||
Vue.use(Vuex);
|
||||
const store = new Vuex.Store({
|
||||
@@ -10,17 +10,18 @@ const store = new Vuex.Store({
|
||||
},
|
||||
state: {
|
||||
drawer: undefined,
|
||||
darkMode: false,
|
||||
pageTitle: undefined,
|
||||
},
|
||||
mutations: {
|
||||
toggleDrawer (state) {
|
||||
state.drawer = !state.drawer;
|
||||
},
|
||||
setDrawer(state, value){
|
||||
setDrawer (state, value) {
|
||||
state.drawer = value;
|
||||
},
|
||||
setDarkMode(state, value){
|
||||
state.darkMode = value;
|
||||
setPageTitle (state, value) {
|
||||
state.pageTitle = value;
|
||||
document.title = value;
|
||||
},
|
||||
},
|
||||
});
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
Accounts.oauth.registerService('patreon');
|
||||
console.log('accounts-patreon');
|
||||
|
||||
if (Meteor.isClient) {
|
||||
const loginWithPatreon = (options, callback) => {
|
||||
|
||||
@@ -1,5 +1,4 @@
|
||||
Patreon = {};
|
||||
console.log('patreon-oauth');
|
||||
|
||||
// Request Patreon credentials for the user
|
||||
// @param options {optional}
|
||||
@@ -33,7 +32,6 @@ Patreon.requestCredential = (options, credentialRequestCompleteCallback) => {
|
||||
const flatScope = scope.map(encodeURIComponent).join(' ');
|
||||
//const flatScope = encodeURIComponent(scope.join(','));
|
||||
|
||||
console.log({flatScope})
|
||||
const loginStyle = OAuth._loginStyle('patreon', config, options);
|
||||
|
||||
const loginUrl =
|
||||
|
||||
Reference in New Issue
Block a user