Compare commits
8 Commits
2.0-beta.2
...
2.0-beta.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b9ae337a64 | ||
|
|
4dc0a6159b | ||
|
|
e00dfe1532 | ||
|
|
28e1fcabd5 | ||
|
|
2c0496b44b | ||
|
|
89adda60ec | ||
|
|
8c3710cda3 | ||
|
|
b501b9d830 |
@@ -7,6 +7,7 @@ export default class ComputationMemo {
|
||||
constructor(props, creature){
|
||||
this.statsByVariableName = {};
|
||||
this.constantsByVariableName = {};
|
||||
this.constantsById = {};
|
||||
this.extraStatsByVariableName = {};
|
||||
this.statsById = {};
|
||||
this.originalPropsById = {};
|
||||
@@ -77,11 +78,7 @@ export default class ComputationMemo {
|
||||
}
|
||||
addConstant(prop){
|
||||
prop = this.registerProperty(prop);
|
||||
if (
|
||||
!this.constantsByVariableName[prop.variableName]
|
||||
){
|
||||
this.constantsByVariableName[prop.variableName] = prop
|
||||
}
|
||||
this.constantsById[prop._id] = prop;
|
||||
}
|
||||
registerProperty(prop){
|
||||
this.originalPropsById[prop._id] = cloneDeep(prop);
|
||||
|
||||
@@ -112,13 +112,14 @@ function combineSkill(stat, aggregator, memo){
|
||||
let profBonus = profBonusStat && profBonusStat.value;
|
||||
|
||||
if (typeof profBonus !== 'number' && memo.statsByVariableName['level']){
|
||||
let level = memo.statsByVariableName['level'].value;
|
||||
let levelProp = memo.statsByVariableName['level'];
|
||||
let level = levelProp.value;
|
||||
profBonus = Math.ceil(level / 4) + 1;
|
||||
if (level._id){
|
||||
stat.dependencies = union(stat.dependencies, [level._id]);
|
||||
if (levelProp._id){
|
||||
stat.dependencies = union(stat.dependencies, [levelProp._id]);
|
||||
}
|
||||
if (level.dependencies){
|
||||
stat.dependencies = union(stat.dependencies, level.dependencies);
|
||||
if (levelProp.dependencies){
|
||||
stat.dependencies = union(stat.dependencies, levelProp.dependencies);
|
||||
}
|
||||
} else {
|
||||
stat.dependencies = union(
|
||||
|
||||
@@ -3,4 +3,10 @@ import applyToggles from '/imports/api/creature/computation/engine/applyToggles.
|
||||
export default function computeConstant(constant, memo){
|
||||
// Apply any toggles
|
||||
applyToggles(constant, memo);
|
||||
if (constant.deactivatedByToggle) return;
|
||||
if (
|
||||
!memo.constantsByVariableName[constant.variableName]
|
||||
){
|
||||
memo.constantsByVariableName[constant.variableName] = constant
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,11 @@
|
||||
import evaluateCalculation from '/imports/api/creature/computation/engine/evaluateCalculation.js';
|
||||
import ConstantNode from '/imports/parser/parseTree/ConstantNode.js';
|
||||
import applyToggles from '/imports/api/creature/computation/engine/applyToggles.js';
|
||||
import { union } from 'lodash';
|
||||
|
||||
export default function computeEndStepProperty(prop, memo){
|
||||
applyToggles(prop, memo);
|
||||
|
||||
switch (prop.type){
|
||||
case 'action':
|
||||
case 'spell':
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { forOwn, has, union } from 'lodash';
|
||||
import applyToggles from '/imports/api/creature/computation/engine/applyToggles.js';
|
||||
|
||||
export default function computeLevels(memo){
|
||||
computeClassLevels(memo);
|
||||
@@ -7,11 +8,13 @@ export default function computeLevels(memo){
|
||||
|
||||
function computeClassLevels(memo){
|
||||
forOwn(memo.classLevelsById, classLevel => {
|
||||
applyToggles(classLevel, memo);
|
||||
// class levels are mutually dependent
|
||||
classLevel.dependencies = union(
|
||||
classLevel.dependencies,
|
||||
Object.keys(memo.classLevelsById)
|
||||
);
|
||||
if (classLevel.deactivatedByToggle) return;
|
||||
let name = classLevel.variableName;
|
||||
let stat = memo.statsByVariableName[name];
|
||||
if (!stat){
|
||||
@@ -29,7 +32,7 @@ function computeClassLevels(memo){
|
||||
|
||||
function computeTotalLevel(memo){
|
||||
let currentLevel = memo.statsByVariableName['level'];
|
||||
if (!currentLevel){
|
||||
if (!currentLevel || currentLevel.deactivatedByToggle){
|
||||
currentLevel = {
|
||||
value: 0,
|
||||
dependencies: [],
|
||||
|
||||
@@ -9,7 +9,7 @@ import computeConstant from '/imports/api/creature/computation/engine/computeCon
|
||||
|
||||
export default function computeMemo(memo){
|
||||
// Compute all constants that could be used
|
||||
forOwn(memo.constantsByVariableName, constant => {
|
||||
forOwn(memo.constantsById, constant => {
|
||||
computeConstant (constant, memo);
|
||||
});
|
||||
// Compute level
|
||||
|
||||
@@ -22,28 +22,25 @@ export default function computeStat(stat, memo){
|
||||
// Apply any toggles
|
||||
applyToggles(stat, memo);
|
||||
|
||||
if (!stat.deactivatedByToggle){
|
||||
// Compute and aggregate all the effects
|
||||
let aggregator = new EffectAggregator(stat, memo)
|
||||
each(stat.computationDetails.effects, (effect) => {
|
||||
computeEffect(effect, memo);
|
||||
if (effect._id){
|
||||
stat.dependencies = union(
|
||||
stat.dependencies,
|
||||
[effect._id]
|
||||
);
|
||||
}
|
||||
// Compute and aggregate all the effects
|
||||
let aggregator = new EffectAggregator(stat, memo)
|
||||
each(stat.computationDetails.effects, (effect) => {
|
||||
computeEffect(effect, memo);
|
||||
if (effect.deactivatedByToggle) return;
|
||||
if (effect._id){
|
||||
stat.dependencies = union(
|
||||
stat.dependencies,
|
||||
effect.dependencies
|
||||
)
|
||||
if (!effect.deactivatedByToggle){
|
||||
aggregator.addEffect(effect);
|
||||
}
|
||||
});
|
||||
// Conglomerate all the effects to compute the final stat values
|
||||
combineStat(stat, aggregator, memo);
|
||||
}
|
||||
[effect._id]
|
||||
);
|
||||
}
|
||||
stat.dependencies = union(
|
||||
stat.dependencies,
|
||||
effect.dependencies
|
||||
)
|
||||
aggregator.addEffect(effect);
|
||||
});
|
||||
// Conglomerate all the effects to compute the final stat values
|
||||
combineStat(stat, aggregator, memo);
|
||||
// Mark the attribute as computed
|
||||
stat.computationDetails.computed = true;
|
||||
stat.computationDetails.busyComputing = false;
|
||||
|
||||
@@ -8,7 +8,10 @@ export default function writeAlteredProperties(memo){
|
||||
// Loop through all properties on the memo
|
||||
forOwn(memo.propsById, changed => {
|
||||
let schema = propertySchemasIndex[changed.type];
|
||||
if (!schema) return;
|
||||
if (!schema){
|
||||
console.warn('No schema for ' + changed.type);
|
||||
return;
|
||||
}
|
||||
let extraIds = changed.computationDetails.idsOfSameName;
|
||||
let ids;
|
||||
if (extraIds && extraIds.length){
|
||||
|
||||
@@ -50,7 +50,7 @@ const damagePropertiesByName = new ValidatedMethod({
|
||||
damagePropertyWork({property, operation, value});
|
||||
lastProperty = property;
|
||||
});
|
||||
recomputePropertyDependencies(lastProperty);
|
||||
if (lastProperty) recomputePropertyDependencies(lastProperty);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
@@ -4,21 +4,22 @@ import { ComputedOnlyAdjustmentSchema } from '/imports/api/properties/Adjustment
|
||||
import { ComputedOnlyAttackSchema } from '/imports/api/properties/Attacks.js';
|
||||
import { ComputedOnlyAttributeSchema } from '/imports/api/properties/Attributes.js';
|
||||
import { ComputedOnlyBuffSchema } from '/imports/api/properties/Buffs.js';
|
||||
// import { ClassLevelSchema } from '/imports/api/properties/ClassLevels.js';
|
||||
import { ClassLevelSchema } from '/imports/api/properties/ClassLevels.js';
|
||||
import { ConstantSchema } from '/imports/api/properties/Constants.js';
|
||||
import { ComputedOnlyContainerSchema } from '/imports/api/properties/Containers.js';
|
||||
import { ComputedOnlyDamageSchema } from '/imports/api/properties/Damages.js';
|
||||
import { DamageMultiplierSchema } from '/imports/api/properties/DamageMultipliers.js';
|
||||
import { ComputedOnlyEffectSchema } from '/imports/api/properties/Effects.js';
|
||||
import { ComputedOnlyFeatureSchema } from '/imports/api/properties/Features.js';
|
||||
// import { FolderSchema } from '/imports/api/properties/Folders.js';
|
||||
import { FolderSchema } from '/imports/api/properties/Folders.js';
|
||||
import { ComputedOnlyItemSchema } from '/imports/api/properties/Items.js';
|
||||
import { ComputedOnlyNoteSchema } from '/imports/api/properties/Notes.js';
|
||||
// import { ProficiencySchema } from '/imports/api/properties/Proficiencies.js';
|
||||
import { ProficiencySchema } from '/imports/api/properties/Proficiencies.js';
|
||||
import { ComputedOnlyRollSchema } from '/imports/api/properties/Rolls.js';
|
||||
import { ComputedOnlySavingThrowSchema } from '/imports/api/properties/SavingThrows.js';
|
||||
import { ComputedOnlySkillSchema } from '/imports/api/properties/Skills.js';
|
||||
import { ComputedOnlySlotSchema } from '/imports/api/properties/Slots.js';
|
||||
// import { SlotFillerSchema } from '/imports/api/properties/SlotFillers.js';
|
||||
import { SlotFillerSchema } from '/imports/api/properties/SlotFillers.js';
|
||||
import { ComputedOnlySpellSchema } from '/imports/api/properties/Spells.js';
|
||||
import { ComputedOnlySpellListSchema } from '/imports/api/properties/SpellLists.js';
|
||||
import { ComputedOnlyToggleSchema } from '/imports/api/properties/Toggles.js';
|
||||
@@ -29,23 +30,25 @@ const propertySchemasIndex = {
|
||||
attack: ComputedOnlyAttackSchema,
|
||||
attribute: ComputedOnlyAttributeSchema,
|
||||
buff: ComputedOnlyBuffSchema,
|
||||
// classLevel: ClassLevelSchema,
|
||||
classLevel: ClassLevelSchema,
|
||||
constant: ConstantSchema,
|
||||
container: ComputedOnlyContainerSchema,
|
||||
damage: ComputedOnlyDamageSchema,
|
||||
damageMultiplier: DamageMultiplierSchema,
|
||||
effect: ComputedOnlyEffectSchema,
|
||||
feature: ComputedOnlyFeatureSchema,
|
||||
// folder: FolderSchema,
|
||||
folder: FolderSchema,
|
||||
item: ComputedOnlyItemSchema,
|
||||
note: ComputedOnlyNoteSchema,
|
||||
// proficiency: ProficiencySchema,
|
||||
proficiency: ProficiencySchema,
|
||||
propertySlot: ComputedOnlySlotSchema,
|
||||
roll: ComputedOnlyRollSchema,
|
||||
savingThrow: ComputedOnlySavingThrowSchema,
|
||||
skill: ComputedOnlySkillSchema,
|
||||
slotFiller: SlotFillerSchema,
|
||||
spellList: ComputedOnlySpellListSchema,
|
||||
spell: ComputedOnlySpellSchema,
|
||||
toggle: ComputedOnlyToggleSchema,
|
||||
container: ComputedOnlyContainerSchema,
|
||||
item: ComputedOnlyItemSchema,
|
||||
any: new SimpleSchema({}),
|
||||
};
|
||||
|
||||
|
||||
@@ -25,38 +25,50 @@ Meteor.publish('libraries', function(){
|
||||
{owner: this.userId},
|
||||
{writers: this.userId},
|
||||
{readers: this.userId},
|
||||
{_id: {$in: subs}},
|
||||
{ _id: {$in: subs}, public: true },
|
||||
]
|
||||
}, {
|
||||
sort: {name: 1}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
Meteor.publish('library', function(libraryId){
|
||||
if (!libraryId) return [];
|
||||
libraryIdSchema.validate({libraryId});
|
||||
this.autorun(function (){
|
||||
let userId = this.userId;
|
||||
let library = Libraries.findOne(libraryId);
|
||||
try { assertViewPermission(library, userId) }
|
||||
catch(e){
|
||||
return this.error(e);
|
||||
}
|
||||
return Libraries.find({
|
||||
_id: libraryId,
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
let libraryIdSchema = new SimpleSchema({
|
||||
libraryIds: {
|
||||
type: Array,
|
||||
},
|
||||
'libraryIds.$':{
|
||||
libraryId:{
|
||||
type: String,
|
||||
regEx: SimpleSchema.RegEx.Id,
|
||||
},
|
||||
});
|
||||
|
||||
Meteor.publish('libraryNodes', function(libraryIds){
|
||||
libraryIdSchema.validate({libraryIds});
|
||||
if (!libraryIds.length) return [];
|
||||
Meteor.publish('libraryNodes', function(libraryId){
|
||||
if (!libraryId) return [];
|
||||
libraryIdSchema.validate({libraryId});
|
||||
this.autorun(function (){
|
||||
let userId = this.userId;
|
||||
for (let i in libraryIds){
|
||||
let libraryId = libraryIds[i];
|
||||
let library = Libraries.findOne(libraryId);
|
||||
try { assertViewPermission(library, userId) }
|
||||
catch(e){
|
||||
return this.error(e);
|
||||
}
|
||||
let library = Libraries.findOne(libraryId);
|
||||
try { assertViewPermission(library, userId) }
|
||||
catch(e){
|
||||
return this.error(e);
|
||||
}
|
||||
return [
|
||||
LibraryNodes.find({
|
||||
'ancestors.id': {$in: libraryIds},
|
||||
'ancestors.id': libraryId,
|
||||
}, {
|
||||
sort: {order: 1},
|
||||
}),
|
||||
|
||||
@@ -5,15 +5,15 @@
|
||||
right
|
||||
clipped
|
||||
>
|
||||
<log-tab :creature-id="$route.params.id" />
|
||||
<character-log :creature-id="$route.params.id" />
|
||||
</v-navigation-drawer>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import LogTab from '/imports/ui/log/CharacterLog.vue';
|
||||
import CharacterLog from '/imports/ui/log/CharacterLog.vue';
|
||||
export default {
|
||||
components: {
|
||||
LogTab,
|
||||
CharacterLog,
|
||||
},
|
||||
computed: {
|
||||
drawer: {
|
||||
|
||||
@@ -19,13 +19,27 @@
|
||||
>
|
||||
<v-spacer />
|
||||
<v-switch
|
||||
v-if="!$route.params.id || canEditLibrary"
|
||||
v-model="organize"
|
||||
label="Organize"
|
||||
class="mx-3"
|
||||
style="flex-grow: 0; height: 32px;"
|
||||
/>
|
||||
</v-toolbar>
|
||||
<div
|
||||
v-if="$route.params.id"
|
||||
style="width: 100%; height: 100%; overflow: auto;"
|
||||
>
|
||||
<library-contents-container
|
||||
:library-id="$route.params.id"
|
||||
:organize-mode="organize"
|
||||
:selected-node-id="selected"
|
||||
should-subscribe
|
||||
@selected="clickNode"
|
||||
/>
|
||||
</div>
|
||||
<library-browser
|
||||
v-else
|
||||
edit-mode
|
||||
:organize-mode="organize"
|
||||
:selected-node-id="selected"
|
||||
@@ -53,14 +67,17 @@ import LibraryBrowser from '/imports/ui/library/LibraryBrowser.vue';
|
||||
import LibraryNodeDialog from '/imports/ui/library/LibraryNodeDialog.vue';
|
||||
import LibraryNodes from '/imports/api/library/LibraryNodes.js';
|
||||
import Libraries from '/imports/api/library/Libraries.js';
|
||||
import LibraryContentsContainer from '/imports/ui/library/LibraryContentsContainer.vue';
|
||||
import { getPropertyName } from '/imports/constants/PROPERTIES.js';
|
||||
import isDarkColor from '/imports/ui/utility/isDarkColor.js';
|
||||
import { assertEditPermission } from '/imports/api/sharing/sharingPermissions.js';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
TreeDetailLayout,
|
||||
LibraryBrowser,
|
||||
LibraryNodeDialog,
|
||||
LibraryContentsContainer,
|
||||
},
|
||||
props: {
|
||||
selection: Boolean,
|
||||
@@ -112,11 +129,34 @@ export default {
|
||||
getPropertyName,
|
||||
},
|
||||
meteor: {
|
||||
$subscribe: {
|
||||
'library'(){
|
||||
if (this.$route.params.id){
|
||||
return [this.$route.params.id];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
},
|
||||
},
|
||||
libraries(){
|
||||
return Libraries.find({}, {
|
||||
sort: {name: 1}
|
||||
}).fetch();
|
||||
},
|
||||
library(){
|
||||
let libraryId = this.$route.params.id;
|
||||
if (!libraryId) return;
|
||||
return Libraries.findOne(libraryId);
|
||||
},
|
||||
canEditLibrary(){
|
||||
if (!this.$route.params.id) return;
|
||||
try {
|
||||
assertEditPermission(this.library, Meteor.userId());
|
||||
return true;
|
||||
} catch (e){
|
||||
return false;
|
||||
}
|
||||
},
|
||||
selectedNode(){
|
||||
return LibraryNodes.findOne({
|
||||
_id: this.selected,
|
||||
|
||||
@@ -11,7 +11,7 @@
|
||||
expand
|
||||
>
|
||||
<v-expansion-panel-content
|
||||
v-for="library in libraries"
|
||||
v-for="(library, index) in libraries"
|
||||
:key="library._id"
|
||||
lazy
|
||||
:data-id="library._id"
|
||||
@@ -24,9 +24,10 @@
|
||||
<v-card flat>
|
||||
<library-contents-container
|
||||
:library-id="library._id"
|
||||
:organize-mode="organizeMode"
|
||||
:organize-mode="organizeMode && editPermission(library)"
|
||||
:edit-mode="editMode"
|
||||
:selected-node-id="selectedNodeId"
|
||||
:should-subscribe="expandedLibrary[index]"
|
||||
@selected="e => $emit('selected', e)"
|
||||
/>
|
||||
<v-card-actions>
|
||||
@@ -47,9 +48,9 @@
|
||||
small
|
||||
icon
|
||||
:disabled="!editPermission(library)"
|
||||
@click="editLibrary(library._id)"
|
||||
@click="$router.push(`/library/${library._id}`)"
|
||||
>
|
||||
<v-icon>create</v-icon>
|
||||
<v-icon>arrow_forward</v-icon>
|
||||
</v-btn>
|
||||
</v-card-actions>
|
||||
</v-card>
|
||||
@@ -89,22 +90,11 @@ export default {
|
||||
selectedNodeId: String,
|
||||
},
|
||||
data(){ return {
|
||||
expandedLibrary: null,
|
||||
expandedLibrary: [],
|
||||
};},
|
||||
meteor: {
|
||||
$subscribe: {
|
||||
'libraries': [],
|
||||
'libraryNodes'(){
|
||||
if (!this.expandedLibrary) return [[]];
|
||||
let libraryIds = [];
|
||||
this.expandedLibrary.forEach((expanded, index) => {
|
||||
if (expanded){
|
||||
let library = this.libraries[index];
|
||||
if (library) libraryIds.push(library._id)
|
||||
}
|
||||
});
|
||||
return [libraryIds];
|
||||
}
|
||||
},
|
||||
libraries(){
|
||||
return Libraries.find({}, {
|
||||
@@ -127,6 +117,7 @@ export default {
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
log: console.log,
|
||||
insertLibrary(){
|
||||
if (this.paidBenefits){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
|
||||
@@ -1,13 +1,30 @@
|
||||
<template lang="html">
|
||||
<tree-node-list
|
||||
group="library"
|
||||
:children="libraryChildren"
|
||||
:organize="organizeMode"
|
||||
:selected-node-id="selectedNodeId"
|
||||
@selected="e => $emit('selected', e)"
|
||||
@reordered="reordered"
|
||||
@reorganized="reorganized"
|
||||
/>
|
||||
<v-fade-transition
|
||||
hide-on-leave
|
||||
>
|
||||
<tree-node-list
|
||||
v-if="slowShouldSubscribe && $subReady.libraryNodes"
|
||||
group="library"
|
||||
:children="libraryChildren"
|
||||
:organize="organizeMode"
|
||||
:selected-node-id="selectedNodeId"
|
||||
@selected="e => $emit('selected', e)"
|
||||
@reordered="reordered"
|
||||
@reorganized="reorganized"
|
||||
/>
|
||||
<v-layout
|
||||
v-else
|
||||
row
|
||||
align-center
|
||||
justify-center
|
||||
style="width: 100%;"
|
||||
>
|
||||
<v-progress-circular
|
||||
color="primary"
|
||||
:indeterminate="slowShouldSubscribe"
|
||||
/>
|
||||
</v-layout>
|
||||
</v-fade-transition>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
@@ -25,8 +42,36 @@
|
||||
libraryId: String,
|
||||
organizeMode: Boolean,
|
||||
selectedNodeId: String,
|
||||
shouldSubscribe: Boolean,
|
||||
},
|
||||
data(){return {
|
||||
slowShouldSubscribe: this.shouldSubscribe,
|
||||
};},
|
||||
watch:{
|
||||
shouldSubscribe(newValue){
|
||||
if (this.timeoutId){
|
||||
clearTimeout(this.timeoutId);
|
||||
delete this.timeoutId;
|
||||
}
|
||||
if (newValue){
|
||||
this.slowShouldSubscribe = newValue
|
||||
} else {
|
||||
this.timeoutId = setTimeout(()=>{
|
||||
this.slowShouldSubscribe = newValue
|
||||
}, 2000);
|
||||
}
|
||||
}
|
||||
},
|
||||
meteor: {
|
||||
$subscribe: {
|
||||
'libraryNodes'(){
|
||||
if (this.slowShouldSubscribe){
|
||||
return [this.libraryId];
|
||||
} else {
|
||||
return [];
|
||||
}
|
||||
}
|
||||
},
|
||||
library(){
|
||||
return Libraries.findOne(this.libraryId);
|
||||
},
|
||||
|
||||
@@ -1,121 +0,0 @@
|
||||
<template lang="html">
|
||||
<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
|
||||
v-model="organize"
|
||||
label="Organize"
|
||||
class="mx-3"
|
||||
style="flex-grow: 0; height: 32px;"
|
||||
/>
|
||||
</v-toolbar>
|
||||
<library-contents-container
|
||||
:library-id="$route.params.id"
|
||||
: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
|
||||
:model="selectedNode"
|
||||
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 PropertyViewer from '/imports/ui/properties/shared/PropertyViewer.vue';
|
||||
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';
|
||||
import LibraryContentsContainer from '/imports/ui/library/LibraryContentsContainer.vue';
|
||||
|
||||
export default {
|
||||
components: {
|
||||
LibraryContentsContainer,
|
||||
PropertyViewer,
|
||||
PropertyIcon,
|
||||
},
|
||||
data(){ return {
|
||||
organize: false,
|
||||
selected: undefined,
|
||||
};},
|
||||
watch:{
|
||||
selectedNode(val){
|
||||
this.$emit('selected', val)
|
||||
},
|
||||
'library.name'(value){
|
||||
this.$store.commit('setPageTitle', value || 'Library');
|
||||
},
|
||||
},
|
||||
methods: {
|
||||
editLibraryNode(){
|
||||
this.$store.commit('pushDialogStack', {
|
||||
component: 'library-node-edit-dialog',
|
||||
elementId: 'selected-node-card',
|
||||
data: {_id: this.selected},
|
||||
});
|
||||
},
|
||||
getPropertyName,
|
||||
},
|
||||
meteor: {
|
||||
$subscribe: {
|
||||
'libraries': [],
|
||||
},
|
||||
library(){
|
||||
return Libraries.findOne(this.$route.params.id);
|
||||
},
|
||||
selectedNode(){
|
||||
return LibraryNodes.findOne({
|
||||
_id: this.selected,
|
||||
removed: {$ne: true}
|
||||
});
|
||||
}
|
||||
}
|
||||
};
|
||||
</script>
|
||||
|
||||
<style lang="css" scoped>
|
||||
</style>
|
||||
@@ -1,28 +1,53 @@
|
||||
<template lang="html">
|
||||
<v-toolbar-items>
|
||||
<v-btn
|
||||
v-if="showSubscribeButton"
|
||||
flat
|
||||
:loading="loading"
|
||||
@click="subscribe(!subscribed)"
|
||||
>
|
||||
{{ subscribed ? 'Unsubscribe' : 'Subscribe' }}
|
||||
</v-btn>
|
||||
<v-btn
|
||||
v-if="canEdit"
|
||||
flat
|
||||
icon
|
||||
data-id="library-edit-button"
|
||||
@click="editLibrary(library._id)"
|
||||
>
|
||||
<v-icon>create</v-icon>
|
||||
</v-btn>
|
||||
</v-toolbar-items>
|
||||
<v-toolbar
|
||||
app
|
||||
color="secondary"
|
||||
dark
|
||||
tabs
|
||||
extended
|
||||
dense
|
||||
>
|
||||
<v-toolbar-side-icon @click="toggleDrawer" />
|
||||
<v-toolbar-items>
|
||||
<v-btn
|
||||
flat
|
||||
icon
|
||||
@click="$router.push('/library')"
|
||||
>
|
||||
<v-icon>arrow_back</v-icon>
|
||||
</v-btn>
|
||||
</v-toolbar-items>
|
||||
<v-toolbar-title>
|
||||
{{ library && library.name }}
|
||||
</v-toolbar-title>
|
||||
<v-spacer />
|
||||
<v-toolbar-items>
|
||||
<v-btn
|
||||
v-if="showSubscribeButton"
|
||||
flat
|
||||
:loading="loading"
|
||||
@click="subscribe(!subscribed)"
|
||||
>
|
||||
{{ subscribed ? 'Unsubscribe' : 'Subscribe' }}
|
||||
</v-btn>
|
||||
<v-btn
|
||||
v-if="canEdit"
|
||||
flat
|
||||
icon
|
||||
data-id="library-edit-button"
|
||||
@click="editLibrary(library._id)"
|
||||
>
|
||||
<v-icon>settings</v-icon>
|
||||
</v-btn>
|
||||
</v-toolbar-items>
|
||||
</v-toolbar>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import Libraries from '/imports/api/library/Libraries.js';
|
||||
import { assertDocEditPermission } from '/imports/api/sharing/sharingPermissions.js';
|
||||
import { mapMutations } from 'vuex';
|
||||
|
||||
export default {
|
||||
data(){ return {
|
||||
loading: false,
|
||||
@@ -33,8 +58,10 @@ export default {
|
||||
},
|
||||
subscribed(){
|
||||
let libraryId = this.$route.params.id;
|
||||
let subs = Meteor.user().subscribedLibraries;
|
||||
return subs.includes(libraryId);
|
||||
let user = Meteor.user();
|
||||
if (!user) return false;
|
||||
let subs = user.subscribedLibraries;
|
||||
return subs && subs.includes(libraryId);
|
||||
},
|
||||
showSubscribeButton(){
|
||||
let userId = Meteor.userId();
|
||||
@@ -60,6 +87,9 @@ export default {
|
||||
}
|
||||
},
|
||||
methods: {
|
||||
...mapMutations([
|
||||
'toggleDrawer',
|
||||
]),
|
||||
subscribe(value){
|
||||
this.loading = true;
|
||||
Meteor.users.subscribeToLibrary.call({
|
||||
@@ -3,8 +3,10 @@
|
||||
style="height: 100%; overflow: hidden;"
|
||||
class="character-log layout column justify-end"
|
||||
>
|
||||
<div
|
||||
class="log flex layout column reverse align-end pa-3"
|
||||
<v-slide-y-reverse-transition
|
||||
group
|
||||
hide-on-leave
|
||||
class="log-entries flex layout column reverse align-end pa-3"
|
||||
style="overflow: auto;"
|
||||
>
|
||||
<log-entry
|
||||
@@ -12,7 +14,7 @@
|
||||
:key="log._id"
|
||||
:model="log"
|
||||
/>
|
||||
</div>
|
||||
</v-slide-y-reverse-transition>
|
||||
<v-card>
|
||||
<v-text-field
|
||||
v-model="input"
|
||||
@@ -120,4 +122,10 @@ export default {
|
||||
.log-tab p:last-child {
|
||||
margin-bottom: 0;
|
||||
}
|
||||
.theme--dark .log-entries {
|
||||
background: #303030;
|
||||
}
|
||||
.log-entries {
|
||||
background: #fafafa;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -1,16 +0,0 @@
|
||||
<template lang="html">
|
||||
<div>
|
||||
<v-card class="ma-4">
|
||||
<single-library />
|
||||
</v-card>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script>
|
||||
import SingleLibrary from '/imports/ui/library/SingleLibrary.vue';
|
||||
export default {
|
||||
components: {
|
||||
SingleLibrary,
|
||||
},
|
||||
};
|
||||
</script>
|
||||
@@ -6,8 +6,7 @@ import Home from '/imports/ui/pages/Home.vue';
|
||||
import About from '/imports/ui/pages/About.vue';
|
||||
import CharacterList from '/imports/ui/pages/CharacterList.vue';
|
||||
import Library from '/imports/ui/pages/Library.vue';
|
||||
import SingleLibraryPage from '/imports/ui/pages/SingleLibraryPage.vue'
|
||||
import SingleLibraryToolbarItems from '/imports/ui/library/SingleLibraryToolbarItems.vue'
|
||||
import SingleLibraryToolbar from '/imports/ui/library/SingleLibraryToolbar.vue';
|
||||
import CharacterSheetPage from '/imports/ui/pages/CharacterSheetPage.vue';
|
||||
import CharacterSheetToolbar from '/imports/ui/creature/character/CharacterSheetToolbar.vue';
|
||||
import CharacterSheetRightDrawer from '/imports/ui/creature/character/CharacterSheetRightDrawer.vue';
|
||||
@@ -123,8 +122,8 @@ RouterFactory.configure(factory => {
|
||||
name: 'singleLibrary',
|
||||
path: '/library/:id',
|
||||
components: {
|
||||
default: SingleLibraryPage,
|
||||
toolbarItems: SingleLibraryToolbarItems,
|
||||
default: Library,
|
||||
toolbar: SingleLibraryToolbar,
|
||||
},
|
||||
meta: {
|
||||
title: 'Library',
|
||||
|
||||
Reference in New Issue
Block a user