Compare commits
3 Commits
2.0-beta.2
...
2.0-beta.2
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2a983b0a94 | ||
|
|
a5460bba0b | ||
|
|
df361236f5 |
@@ -28,10 +28,14 @@ const removeCreature = new ValidatedMethod({
|
|||||||
},
|
},
|
||||||
run({charId}) {
|
run({charId}) {
|
||||||
assertOwnership(charId, this.userId)
|
assertOwnership(charId, this.userId)
|
||||||
Creatures.remove(charId);
|
this.unblock();
|
||||||
this.unblock();
|
removeCreatureWork(charId)
|
||||||
removeRelatedDocuments(charId);
|
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
|
|
||||||
|
export function removeCreatureWork(creatureId){
|
||||||
|
Creatures.remove(creatureId);
|
||||||
|
removeRelatedDocuments(creatureId);
|
||||||
|
}
|
||||||
|
|
||||||
export default removeCreature;
|
export default removeCreature;
|
||||||
|
|||||||
@@ -118,10 +118,14 @@ const removeLibrary = new ValidatedMethod({
|
|||||||
run({_id}){
|
run({_id}){
|
||||||
let library = Libraries.findOne(_id);
|
let library = Libraries.findOne(_id);
|
||||||
assertOwnership(library, this.userId);
|
assertOwnership(library, this.userId);
|
||||||
Libraries.remove(_id);
|
this.unblock();
|
||||||
this.unblock();
|
removeLibaryWork(_id)
|
||||||
LibraryNodes.remove({'ancestors.id': _id});
|
|
||||||
}
|
}
|
||||||
})
|
});
|
||||||
|
|
||||||
|
export function removeLibaryWork(libraryId){
|
||||||
|
Libraries.remove(libraryId);
|
||||||
|
LibraryNodes.remove({'ancestors.id': libraryId});
|
||||||
|
}
|
||||||
|
|
||||||
export { LibrarySchema, insertLibrary, setLibraryDefault, updateLibraryName, removeLibrary };
|
export { LibrarySchema, insertLibrary, setLibraryDefault, updateLibraryName, removeLibrary };
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
import SimpleSchema from 'simpl-schema';
|
import SimpleSchema from 'simpl-schema';
|
||||||
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||||
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||||
|
import '/imports/api/users/deleteMyAccount.js';
|
||||||
|
|
||||||
const userSchema = new SimpleSchema({
|
const userSchema = new SimpleSchema({
|
||||||
username: {
|
username: {
|
||||||
|
|||||||
61
app/imports/api/users/deleteMyAccount.js
Normal file
61
app/imports/api/users/deleteMyAccount.js
Normal file
@@ -0,0 +1,61 @@
|
|||||||
|
import { ValidatedMethod } from 'meteor/mdg:validated-method';
|
||||||
|
import { RateLimiterMixin } from 'ddp-rate-limiter-mixin';
|
||||||
|
import Libraries, {removeLibaryWork} from '/imports/api/library/Libraries.js';
|
||||||
|
import Creatures from '/imports/api/creature/Creatures.js';
|
||||||
|
import {removeCreatureWork} from '/imports/api/creature/removeCreature.js';
|
||||||
|
|
||||||
|
Meteor.users.deleteMyAccount = new ValidatedMethod({
|
||||||
|
name: 'users.deleteMyAccount',
|
||||||
|
validate: null,
|
||||||
|
mixins: [RateLimiterMixin],
|
||||||
|
rateLimit: {
|
||||||
|
numRequests: 1,
|
||||||
|
timeInterval: 5000,
|
||||||
|
},
|
||||||
|
run(){
|
||||||
|
let userId = Meteor.userId();
|
||||||
|
if (!userId) throw new Meteor.Error('No user',
|
||||||
|
'You must be logged into to delete your account');
|
||||||
|
|
||||||
|
// Delete all creatures
|
||||||
|
let creatures = Creatures.find({owner: userId}, {fields: {_id: 1}}).fetch();
|
||||||
|
creatures.forEach(creature => removeCreatureWork(creature._id));
|
||||||
|
|
||||||
|
// Remove permissions from all creatures
|
||||||
|
Creatures.update({
|
||||||
|
$or: [
|
||||||
|
{writers: userId},
|
||||||
|
{readers: userId},
|
||||||
|
],
|
||||||
|
}, {
|
||||||
|
$pull: {
|
||||||
|
writers: userId,
|
||||||
|
readers: userId
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
multi: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// Delete all libraries
|
||||||
|
let libraries = Libraries.find({owner: userId}, {fields: {_id: 1}}).fetch();
|
||||||
|
libraries.forEach(library => removeLibaryWork(library._id));
|
||||||
|
|
||||||
|
// Remove permissions from all creatures
|
||||||
|
Libraries.update({
|
||||||
|
$or: [
|
||||||
|
{writers: userId},
|
||||||
|
{readers: userId},
|
||||||
|
],
|
||||||
|
}, {
|
||||||
|
$pull: {
|
||||||
|
writers: userId,
|
||||||
|
readers: userId
|
||||||
|
},
|
||||||
|
}, {
|
||||||
|
multi: true,
|
||||||
|
});
|
||||||
|
|
||||||
|
// delete the account
|
||||||
|
Meteor.users.remove(userId);
|
||||||
|
}
|
||||||
|
});
|
||||||
@@ -7,3 +7,4 @@ import '/imports/server/publications/users.js';
|
|||||||
import '/imports/server/publications/icons.js';
|
import '/imports/server/publications/icons.js';
|
||||||
import '/imports/server/publications/tabletops.js';
|
import '/imports/server/publications/tabletops.js';
|
||||||
import '/imports/server/publications/slotFillers.js'
|
import '/imports/server/publications/slotFillers.js'
|
||||||
|
import '/imports/server/publications/ownedDocuments.js'
|
||||||
|
|||||||
15
app/imports/server/publications/ownedDocuments.js
Normal file
15
app/imports/server/publications/ownedDocuments.js
Normal file
@@ -0,0 +1,15 @@
|
|||||||
|
import Creatures from '/imports/api/creature/Creatures.js';
|
||||||
|
import Libraries from '/imports/api/library/Libraries.js';
|
||||||
|
|
||||||
|
Meteor.publish('ownedDocuments', function(){
|
||||||
|
this.autorun(function (){
|
||||||
|
let userId = this.userId;
|
||||||
|
if (!userId) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
return [
|
||||||
|
Creatures.find({owner: userId}),
|
||||||
|
Libraries.find({owner: userId}),
|
||||||
|
]
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -3,6 +3,8 @@
|
|||||||
fab
|
fab
|
||||||
small
|
small
|
||||||
v-bind="$attrs"
|
v-bind="$attrs"
|
||||||
|
:disabled="disabled"
|
||||||
|
:style="disabled ? 'background-color: #616161 !important;' : ''"
|
||||||
@click="$emit('click')"
|
@click="$emit('click')"
|
||||||
>
|
>
|
||||||
<v-icon>{{ icon }}</v-icon>
|
<v-icon>{{ icon }}</v-icon>
|
||||||
@@ -18,7 +20,7 @@
|
|||||||
* component creates a v-btn with a label.
|
* component creates a v-btn with a label.
|
||||||
*/
|
*/
|
||||||
export default {
|
export default {
|
||||||
props: ['icon', 'label'],
|
props: ['icon', 'label', 'disabled'],
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
104
app/imports/ui/creature/character/CharacterSheetFab.vue
Normal file
104
app/imports/ui/creature/character/CharacterSheetFab.vue
Normal file
@@ -0,0 +1,104 @@
|
|||||||
|
<template lang="html">
|
||||||
|
<v-speed-dial
|
||||||
|
v-if="speedDials && speedDials.length"
|
||||||
|
v-model="fab"
|
||||||
|
direction="bottom"
|
||||||
|
>
|
||||||
|
<template #activator>
|
||||||
|
<v-btn
|
||||||
|
v-model="fab"
|
||||||
|
color="primary"
|
||||||
|
fab
|
||||||
|
data-id="insert-creature-property-fab"
|
||||||
|
small
|
||||||
|
>
|
||||||
|
<v-icon>add</v-icon>
|
||||||
|
<v-icon>close</v-icon>
|
||||||
|
</v-btn>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<labeled-fab
|
||||||
|
v-for="type in speedDials"
|
||||||
|
:key="type"
|
||||||
|
color="primary"
|
||||||
|
:data-id="`insert-creature-property-type-${type}`"
|
||||||
|
:label="'New ' + properties[type].name"
|
||||||
|
:icon="properties[type].icon"
|
||||||
|
:disabled="!editPermission"
|
||||||
|
@click="insertPropertyOfType(type)"
|
||||||
|
/>
|
||||||
|
</v-speed-dial>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import LabeledFab from '/imports/ui/components/LabeledFab.vue';
|
||||||
|
import { setDocToLastOrder } from '/imports/api/parenting/order.js';
|
||||||
|
import insertProperty from '/imports/api/creature/creatureProperties/methods/insertProperty.js';
|
||||||
|
import CreatureProperties from '/imports/api/creature/creatureProperties/CreatureProperties.js';
|
||||||
|
import PROPERTIES from '/imports/constants/PROPERTIES.js';
|
||||||
|
|
||||||
|
const tabs = [
|
||||||
|
'stats',
|
||||||
|
'features',
|
||||||
|
'inventory',
|
||||||
|
'spells',
|
||||||
|
'character',
|
||||||
|
'tree',
|
||||||
|
];
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
LabeledFab,
|
||||||
|
},
|
||||||
|
props: {
|
||||||
|
editPermission: Boolean,
|
||||||
|
},
|
||||||
|
data(){return {
|
||||||
|
fab: false,
|
||||||
|
};},
|
||||||
|
computed: {
|
||||||
|
creatureId(){
|
||||||
|
return this.$route.params.id;
|
||||||
|
},
|
||||||
|
tabNumber(){
|
||||||
|
return this.$store.getters.tabById(this.creatureId);
|
||||||
|
},
|
||||||
|
speedDials(){
|
||||||
|
return this.speedDialsByTab[tabs[this.tabNumber]];
|
||||||
|
},
|
||||||
|
speedDialsByTab() { return {
|
||||||
|
'stats': ['attribute', 'skill'],
|
||||||
|
'features': ['feature'],
|
||||||
|
'inventory': ['item', 'container'],
|
||||||
|
'spells': ['spellList', 'spell'],
|
||||||
|
'character': ['note'],
|
||||||
|
};},
|
||||||
|
properties(){
|
||||||
|
return PROPERTIES;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
insertPropertyOfType(type){
|
||||||
|
let that = this;
|
||||||
|
this.$store.commit('pushDialogStack', {
|
||||||
|
component: 'creature-property-creation-dialog',
|
||||||
|
elementId: 'insert-creature-property-type-' + type,
|
||||||
|
data: {
|
||||||
|
forcedType: type,
|
||||||
|
},
|
||||||
|
callback(creatureProperty){
|
||||||
|
if (!creatureProperty) return;
|
||||||
|
creatureProperty.parent = {collection: 'creatures', id: that.creatureId};
|
||||||
|
creatureProperty.ancestors = [ {collection: 'creatures', id: that.creatureId}];
|
||||||
|
setDocToLastOrder({collection: CreatureProperties, doc: creatureProperty});
|
||||||
|
let id = insertProperty.call({creatureProperty});
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
</style>
|
||||||
@@ -5,6 +5,7 @@
|
|||||||
:color="toolbarColor"
|
:color="toolbarColor"
|
||||||
:dark="isDark"
|
:dark="isDark"
|
||||||
:light="!isDark"
|
:light="!isDark"
|
||||||
|
extended
|
||||||
tabs
|
tabs
|
||||||
dense
|
dense
|
||||||
>
|
>
|
||||||
@@ -73,11 +74,12 @@
|
|||||||
>
|
>
|
||||||
<div
|
<div
|
||||||
:key="$route.meta.title"
|
:key="$route.meta.title"
|
||||||
style="width: 100%"
|
class="layout row"
|
||||||
>
|
>
|
||||||
<v-tabs
|
<v-tabs
|
||||||
v-if="creature"
|
v-if="creature"
|
||||||
slot="extension"
|
class="flex"
|
||||||
|
style="min-width: 0"
|
||||||
centered
|
centered
|
||||||
grow
|
grow
|
||||||
max="100px"
|
max="100px"
|
||||||
@@ -106,6 +108,10 @@
|
|||||||
Tree
|
Tree
|
||||||
</v-tab>
|
</v-tab>
|
||||||
</v-tabs>
|
</v-tabs>
|
||||||
|
<character-sheet-fab
|
||||||
|
class="character-sheet-fab"
|
||||||
|
:edit-permission="editPermission"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
</v-fade-transition>
|
</v-fade-transition>
|
||||||
</v-toolbar>
|
</v-toolbar>
|
||||||
@@ -119,8 +125,15 @@ import { theme } from '/imports/ui/theme.js';
|
|||||||
import { assertEditPermission } from '/imports/api/creature/creaturePermissions.js';
|
import { assertEditPermission } from '/imports/api/creature/creaturePermissions.js';
|
||||||
import { updateUserSharePermissions } from '/imports/api/sharing/sharing.js';
|
import { updateUserSharePermissions } from '/imports/api/sharing/sharing.js';
|
||||||
import isDarkColor from '/imports/ui/utility/isDarkColor.js';
|
import isDarkColor from '/imports/ui/utility/isDarkColor.js';
|
||||||
|
import CharacterSheetFab from '/imports/ui/creature/character/CharacterSheetFab.vue';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
|
inject: {
|
||||||
|
context: { default: {} }
|
||||||
|
},
|
||||||
|
components: {
|
||||||
|
CharacterSheetFab,
|
||||||
|
},
|
||||||
data(){return {
|
data(){return {
|
||||||
theme,
|
theme,
|
||||||
}},
|
}},
|
||||||
@@ -231,4 +244,8 @@ export default {
|
|||||||
.character-sheet-toolbar .v-tabs__bar {
|
.character-sheet-toolbar .v-tabs__bar {
|
||||||
background: none !important;
|
background: none !important;
|
||||||
}
|
}
|
||||||
|
.character-sheet-fab {
|
||||||
|
bottom: -24px;
|
||||||
|
margin-right: -8px;
|
||||||
|
}
|
||||||
</style>
|
</style>
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
<template lang="html">
|
<template lang="html">
|
||||||
<selectable-property-dialog v-model="type">
|
<selectable-property-dialog :value="forcedType || type">
|
||||||
<creature-property-insert-form
|
<creature-property-insert-form
|
||||||
:type="type"
|
:type="forcedType || type"
|
||||||
:property-name="getPropertyName(type)"
|
:property-name="getPropertyName(forcedType || type)"
|
||||||
@back="type = undefined"
|
@back="back"
|
||||||
/>
|
/>
|
||||||
</selectable-property-dialog>
|
</selectable-property-dialog>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
@@ -14,15 +14,28 @@ import CreaturePropertyInsertForm from '/imports/ui/creature/creatureProperties/
|
|||||||
import { getPropertyName } from '/imports/constants/PROPERTIES.js';
|
import { getPropertyName } from '/imports/constants/PROPERTIES.js';
|
||||||
|
|
||||||
export default {
|
export default {
|
||||||
data() { return {
|
|
||||||
type: undefined,
|
|
||||||
};},
|
|
||||||
components: {
|
components: {
|
||||||
SelectablePropertyDialog,
|
SelectablePropertyDialog,
|
||||||
CreaturePropertyInsertForm,
|
CreaturePropertyInsertForm,
|
||||||
},
|
},
|
||||||
|
props: {
|
||||||
|
forcedType: {
|
||||||
|
type: String,
|
||||||
|
default: undefined,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
data() { return {
|
||||||
|
type: undefined,
|
||||||
|
};},
|
||||||
methods: {
|
methods: {
|
||||||
getPropertyName,
|
getPropertyName,
|
||||||
|
back(){
|
||||||
|
if (this.forcedType){
|
||||||
|
this.$store.dispatch('popDialogStack');
|
||||||
|
} else {
|
||||||
|
this.type = undefined;
|
||||||
|
}
|
||||||
|
},
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
</script>
|
</script>
|
||||||
|
|||||||
@@ -70,14 +70,22 @@ export default {
|
|||||||
};},
|
};},
|
||||||
watch: {
|
watch: {
|
||||||
type(newType){
|
type(newType){
|
||||||
if (!newType) return;
|
this.changeType(newType);
|
||||||
this.schema = propertySchemasIndex[newType];
|
|
||||||
this.validationContext = this.schema.newContext();
|
|
||||||
let model = this.schema.clean({});
|
|
||||||
model.type = newType;
|
|
||||||
this.model = model;
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
mounted(){
|
||||||
|
this.changeType(this.type);
|
||||||
|
},
|
||||||
|
methods:{
|
||||||
|
changeType(type){
|
||||||
|
if (!type) return;
|
||||||
|
this.schema = propertySchemasIndex[type];
|
||||||
|
this.validationContext = this.schema.newContext();
|
||||||
|
let model = this.schema.clean({});
|
||||||
|
model.type = type;
|
||||||
|
this.model = model;
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import CreaturePropertyCreationDialog from '/imports/ui/creature/creaturePropert
|
|||||||
import CreaturePropertyDialog from '/imports/ui/creature/creatureProperties/CreaturePropertyDialog.vue'
|
import CreaturePropertyDialog from '/imports/ui/creature/creatureProperties/CreaturePropertyDialog.vue'
|
||||||
import CreaturePropertyFromLibraryDialog from '/imports/ui/creature/creatureProperties/CreaturePropertyFromLibraryDialog.vue'
|
import CreaturePropertyFromLibraryDialog from '/imports/ui/creature/creatureProperties/CreaturePropertyFromLibraryDialog.vue'
|
||||||
import DeleteConfirmationDialog from '/imports/ui/dialogStack/DeleteConfirmationDialog.vue';
|
import DeleteConfirmationDialog from '/imports/ui/dialogStack/DeleteConfirmationDialog.vue';
|
||||||
|
import DeleteUserAccountDialog from '/imports/ui/user/DeleteUserAccountDialog.vue';
|
||||||
import ExperienceInsertDialog from '/imports/ui/creature/experiences/ExperienceInsertDialog.vue';
|
import ExperienceInsertDialog from '/imports/ui/creature/experiences/ExperienceInsertDialog.vue';
|
||||||
import ExperienceListDialog from '/imports/ui/creature/experiences/ExperienceListDialog.vue';
|
import ExperienceListDialog from '/imports/ui/creature/experiences/ExperienceListDialog.vue';
|
||||||
import InviteDialog from '/imports/ui/user/InviteDialog.vue';
|
import InviteDialog from '/imports/ui/user/InviteDialog.vue';
|
||||||
@@ -26,6 +27,7 @@ export default {
|
|||||||
CreaturePropertyDialog,
|
CreaturePropertyDialog,
|
||||||
CreaturePropertyFromLibraryDialog,
|
CreaturePropertyFromLibraryDialog,
|
||||||
DeleteConfirmationDialog,
|
DeleteConfirmationDialog,
|
||||||
|
DeleteUserAccountDialog,
|
||||||
ExperienceInsertDialog,
|
ExperienceInsertDialog,
|
||||||
ExperienceListDialog,
|
ExperienceListDialog,
|
||||||
InviteDialog,
|
InviteDialog,
|
||||||
|
|||||||
@@ -13,7 +13,7 @@
|
|||||||
name="toolbar"
|
name="toolbar"
|
||||||
/>
|
/>
|
||||||
<v-toolbar
|
<v-toolbar
|
||||||
v-if="!$route.matched[0].components.toolbar"
|
v-if="!$route.matched[0] || !$route.matched[0].components.toolbar"
|
||||||
app
|
app
|
||||||
color="secondary"
|
color="secondary"
|
||||||
dark
|
dark
|
||||||
|
|||||||
@@ -141,6 +141,19 @@
|
|||||||
</template>
|
</template>
|
||||||
</v-list>
|
</v-list>
|
||||||
</template>
|
</template>
|
||||||
|
<v-layout
|
||||||
|
row
|
||||||
|
justify-end
|
||||||
|
class="mt-3"
|
||||||
|
>
|
||||||
|
<v-btn
|
||||||
|
color="error"
|
||||||
|
data-id="delete-account-btn"
|
||||||
|
@click="deleteAccount"
|
||||||
|
>
|
||||||
|
Delete Account
|
||||||
|
</v-btn>
|
||||||
|
</v-layout>
|
||||||
</v-card>
|
</v-card>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@@ -270,6 +283,12 @@
|
|||||||
this.updatePatreonLoading = false;
|
this.updatePatreonLoading = false;
|
||||||
if (error) this.updatePatreonError = error;
|
if (error) this.updatePatreonError = error;
|
||||||
});
|
});
|
||||||
|
},
|
||||||
|
deleteAccount(){
|
||||||
|
this.$store.commit('pushDialogStack', {
|
||||||
|
component: 'delete-user-account-dialog',
|
||||||
|
elementId: 'delete-account-btn',
|
||||||
|
});
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -17,7 +17,7 @@
|
|||||||
>
|
>
|
||||||
$vuetify.icons.weight
|
$vuetify.icons.weight
|
||||||
</v-icon>
|
</v-icon>
|
||||||
{{ (model.contentsWeight ? 0 : model.contentsWeight || 0) + (model.weight || 0) }}
|
{{ (model.contentsWeightless ? 0 : model.contentsWeight || 0) + (model.weight || 0) }}
|
||||||
</v-toolbar-title>
|
</v-toolbar-title>
|
||||||
<v-toolbar-title
|
<v-toolbar-title
|
||||||
class="layout row align-center"
|
class="layout row align-center"
|
||||||
|
|||||||
153
app/imports/ui/user/DeleteUserAccountDialog.vue
Normal file
153
app/imports/ui/user/DeleteUserAccountDialog.vue
Normal file
@@ -0,0 +1,153 @@
|
|||||||
|
<template lang="html">
|
||||||
|
<dialog-base>
|
||||||
|
<v-toolbar-title slot="toolbar">
|
||||||
|
Delete User Account
|
||||||
|
</v-toolbar-title>
|
||||||
|
<div>
|
||||||
|
<h2>Are you sure you want to delete your account?</h2>
|
||||||
|
<v-alert
|
||||||
|
:value="true"
|
||||||
|
icon="warning"
|
||||||
|
color="error"
|
||||||
|
outline
|
||||||
|
>
|
||||||
|
Deleted accounts can not be recovered
|
||||||
|
</v-alert>
|
||||||
|
<p>We will immediately delete your account and all of your data</p>
|
||||||
|
<p>Your username will become available to anyone on DiceCloud</p>
|
||||||
|
<template v-if="characters.length">
|
||||||
|
<h3 v-if="characters.length > 1">
|
||||||
|
These {{ characters.length }} characters will be deleted:
|
||||||
|
</h3>
|
||||||
|
<h3 v-else>
|
||||||
|
This character will be deleted:
|
||||||
|
</h3>
|
||||||
|
<v-list>
|
||||||
|
<creature-list-tile
|
||||||
|
v-for="character in characters"
|
||||||
|
:key="character._id"
|
||||||
|
:model="character"
|
||||||
|
/>
|
||||||
|
</v-list>
|
||||||
|
</template>
|
||||||
|
<template v-if="libraries.length">
|
||||||
|
<h3 v-if="libraries.length > 1">
|
||||||
|
These {{ libraries.length }} libraries will be deleted:
|
||||||
|
</h3>
|
||||||
|
<h3 v-else>
|
||||||
|
This library will be deleted:
|
||||||
|
</h3>
|
||||||
|
<v-list>
|
||||||
|
<creature-list-tile
|
||||||
|
v-for="library in libraries"
|
||||||
|
:key="library._id"
|
||||||
|
:model="library"
|
||||||
|
/>
|
||||||
|
</v-list>
|
||||||
|
</template>
|
||||||
|
<v-layout
|
||||||
|
column
|
||||||
|
align-start
|
||||||
|
>
|
||||||
|
<v-text-field
|
||||||
|
v-if="user.username"
|
||||||
|
v-model="usernameInput"
|
||||||
|
label="Type your username or email"
|
||||||
|
style="width: 350px;"
|
||||||
|
:error-messages="usernameInputValid ? undefined : ' '"
|
||||||
|
:append-icon="usernameInputValid ? 'done' : undefined"
|
||||||
|
/>
|
||||||
|
<v-text-field
|
||||||
|
v-model="verificationInput"
|
||||||
|
label="To verify type 'delete my account'"
|
||||||
|
style="width: 350px;"
|
||||||
|
:error-messages="verificationInputValid ? undefined : ' '"
|
||||||
|
:append-icon="verificationInputValid ? 'done' : undefined"
|
||||||
|
/>
|
||||||
|
<v-btn
|
||||||
|
class="mt-4"
|
||||||
|
color="error"
|
||||||
|
:disabled="!valid"
|
||||||
|
@click="deleteAccount"
|
||||||
|
>
|
||||||
|
Permanently delete account
|
||||||
|
</v-btn>
|
||||||
|
</v-layout>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
slot="actions"
|
||||||
|
class="layout row justify-end"
|
||||||
|
>
|
||||||
|
<v-btn
|
||||||
|
flat
|
||||||
|
@click="$store.dispatch('popDialogStack')"
|
||||||
|
>
|
||||||
|
Cancel
|
||||||
|
</v-btn>
|
||||||
|
</div>
|
||||||
|
</dialog-base>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
import DialogBase from '/imports/ui/dialogStack/DialogBase.vue';
|
||||||
|
import Creatures from '/imports/api/creature/Creatures.js';
|
||||||
|
import Libraries from '/imports/api/library/Libraries.js';
|
||||||
|
import CreatureListTile from '/imports/ui/creature/CreatureListTile.vue';
|
||||||
|
|
||||||
|
export default {
|
||||||
|
components: {
|
||||||
|
DialogBase,
|
||||||
|
CreatureListTile,
|
||||||
|
},
|
||||||
|
data(){return {
|
||||||
|
usernameInput: '',
|
||||||
|
verificationInput: '',
|
||||||
|
};},
|
||||||
|
meteor: {
|
||||||
|
$subscribe: {
|
||||||
|
'ownedDocuments'(){
|
||||||
|
return [];
|
||||||
|
},
|
||||||
|
},
|
||||||
|
characters(){
|
||||||
|
return Creatures.find({owner: Meteor.userId()});
|
||||||
|
},
|
||||||
|
libraries(){
|
||||||
|
return Libraries.find({owner: Meteor.userId()});
|
||||||
|
},
|
||||||
|
user(){
|
||||||
|
return Meteor.user();
|
||||||
|
},
|
||||||
|
},
|
||||||
|
computed:{
|
||||||
|
usernameInputValid(){
|
||||||
|
let username = this.user.username;
|
||||||
|
if (!username) return true;
|
||||||
|
let input = this.usernameInput;
|
||||||
|
if (!input) return false;
|
||||||
|
if (input.toLowerCase() === username.toLowerCase()){
|
||||||
|
return true;
|
||||||
|
} else {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
verificationInputValid(){
|
||||||
|
let input = this.verificationInput || '';
|
||||||
|
return input.toLowerCase() === 'delete my account'
|
||||||
|
},
|
||||||
|
valid(){
|
||||||
|
return this.usernameInputValid && this.verificationInputValid;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
methods: {
|
||||||
|
deleteAccount(){
|
||||||
|
this.$router.push('/');
|
||||||
|
Meteor.users.deleteMyAccount.call();
|
||||||
|
this.$store.dispatch('popDialogStack');
|
||||||
|
},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="css" scoped>
|
||||||
|
</style>
|
||||||
@@ -25,7 +25,8 @@ for (const name in SVG_ICONS) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Vue.use(VueMeteorTracker);
|
Vue.use(VueMeteorTracker);
|
||||||
Vue.config.meteor.freeze = true
|
Vue.config.meteor.freeze = true;
|
||||||
|
Vue.config.devtools = true;
|
||||||
Vue.use(Vuetify, {
|
Vue.use(Vuetify, {
|
||||||
theme,
|
theme,
|
||||||
iconfont: 'md',
|
iconfont: 'md',
|
||||||
|
|||||||
Reference in New Issue
Block a user