migrates active effect to DocumentV2

feature/applicationv2
macniel 2025-10-15 21:02:56 +02:00
parent 7ea6b4a2e0
commit 626474178d
10 changed files with 323 additions and 282 deletions

View File

@ -1,44 +1,65 @@
export class ActiveEffectSheet extends foundry.appv1.sheets.ItemSheet {
/**@override */
static get defaultOptions() {
return foundry.utils.mergeObject(super.defaultOptions, {
classes: ['dsa41', 'sheet', 'activeeffect'],
width: 520,
height: 480
});
const {DocumentSheetV2, HandlebarsApplicationMixin} = foundry.applications.api
export class ActiveEffectSheet extends HandlebarsApplicationMixin(DocumentSheetV2) {
/** @inheritDoc */
static DEFAULT_OPTIONS = {
position: {width: 520, height: 480},
classes: ['dsa41', 'sheet', 'item', 'activeeffect'],
tag: 'form',
form: {
submitOnChange: true,
closeOnSubmit: false,
handler: ActiveEffectSheet.#onSubmitForm
},
actions: {
openEffect: ActiveEffectSheet.#openEffect,
editImage: DocumentSheetV2.DEFAULT_OPTIONS.actions.editImage,
}
}
/** @inheritDoc */
static PARTS = {
form: {
template: `systems/DSA_4-1/templates/item/activeeffect/main-sheet.hbs`
},
}
static async #openEffect(evt) {
evt.preventDefault()
const {id} = evt.srcElement.dataset
const effect = await this.document.effects.get(id)
effect.sheet.render(true)
}
/**
* Handle form submission
* @this {AdvantageSheet}
* @param {SubmitEvent} event
* @param {HTMLFormElement} form
* @param {FormDataExtended} formData
*/
static async #onSubmitForm(event, form, formData) {
event.preventDefault()
await this.document.update(formData.object) // Note: formData.object
}
/** @override */
get template() {
return `systems/DSA_4-1/templates/item/item-activeeffect-sheet.hbs`;
}
async _prepareContext(options) {
/** @override */
getData() {
// Retrieve the data structure from the base sheet. You can inspect or log
// the context variable to see the structure, but some key properties for
// sheets are the actor object, the data object, whether or not it's
// editable, the items array, and the effects array.
const context = super.getData();
const effects = context.document.getEmbeddedCollection("ActiveEffect").contents;
const context = await super._prepareContext(options)
context.system = context.document.system
const effects = context.document.getEmbeddedCollection("ActiveEffect").contents
if (effects.length > 0) {
context.effectId = effects[0]._id;
context.effectId = effects[0]._id
}
return context;
context.name = context.document.name
context.img = context.document.img
context.notes = context.document.system.notes
return context
}
activateListeners(html) {
super.activateListeners(html);
// Everything below here is only needed if the sheet is editable
if (!this.isEditable) return;
html.on('click', '.editEffects', (evt) => {
const {id} = evt.currentTarget.dataset;
const effect = this.object.effects.get(id);
effect.sheet.render(true);
})
}
}

View File

@ -110,12 +110,12 @@ export class EquipmentSheet extends HandlebarsApplicationMixin(DocumentSheetV2)
}
#prepareMetaContext(context) {
const equipmentData = context.document.system;
context.system = equipmentData;
context.quantity = equipmentData.quantity;
context.description = equipmentData.description;
context.name = context.document.name;
context.img = context.document.img;
const equipmentData = context.document.system
context.system = equipmentData
context.quantity = equipmentData.quantity
context.description = equipmentData.description
context.name = context.document.name
context.img = context.document.img
context.categoryAndOptions = {
options: {
@ -131,8 +131,8 @@ export class EquipmentSheet extends HandlebarsApplicationMixin(DocumentSheetV2)
}
#prepareMeleeContext(context) {
const equipmentData = context.document.system;
context.system = equipmentData;
const equipmentData = context.document.system
context.system = equipmentData
context.meleeSkillsAndOptions = {
options: {
"": "",
@ -156,7 +156,7 @@ export class EquipmentSheet extends HandlebarsApplicationMixin(DocumentSheetV2)
}
#prepareRangedContext(context) {
const equipmentData = context.document.system;
const equipmentData = context.document.system
context.rangedSkillsAndOptions = {
options: {
"": "",
@ -187,14 +187,14 @@ export class EquipmentSheet extends HandlebarsApplicationMixin(DocumentSheetV2)
*/
_prepareTabs(tabGroup) {
const currentTabs = super._prepareTabs(tabGroup);
const currentTabs = super._prepareTabs(tabGroup)
const category = this.document.system.category
/**
*
* @type {[{ApplicationTab}]}
*/
let tabs = currentTabs;
let tabs = currentTabs
if (category.includes("Nahkampfwaffe")) {
tabs.melee = {
@ -223,7 +223,7 @@ export class EquipmentSheet extends HandlebarsApplicationMixin(DocumentSheetV2)
/** @override */
async _prepareContext(options) {
const context = await super._prepareContext(options);
const context = await super._prepareContext(options)
context.price = context.document.system.price
context.weight = context.document.system.weight
@ -239,12 +239,12 @@ export class EquipmentSheet extends HandlebarsApplicationMixin(DocumentSheetV2)
*/
_onRender(context, options) {
this.element.querySelector('.array-editor select').addEventListener('change', (evt) => {
const addingValue = evt.currentTarget.value;
const fieldToTarget = evt.currentTarget.dataset.targetField;
const newSkills = [...this.document.system[fieldToTarget], addingValue];
const addingValue = evt.currentTarget.value
const fieldToTarget = evt.currentTarget.dataset.targetField
const newSkills = [...this.document.system[fieldToTarget], addingValue]
this.document.update({system: {[fieldToTarget]: newSkills}});
evt.currentTarget.value = "";
this.document.update({system: {[fieldToTarget]: newSkills}})
evt.currentTarget.value = ""
})
}

View File

@ -14,6 +14,11 @@
height: 48px;
line-height: 48px;
}
button {
height: 48px;
width: 48px;
}
}
.meta {

View File

@ -72,176 +72,180 @@ $deity_colours_tint: (
}
}
.tab.liturgies {
table {
.dsa41.sheet {
@include coloring('Praios');
@include coloring('Rondra');
@include coloring('Efferd');
@include coloring('Travia');
@include coloring('Boron');
@include coloring('Hesinde');
@include coloring('Firun');
@include coloring('Tsa');
@include coloring('Phex');
@include coloring('Peraine');
@include coloring('Ingerimm');
@include coloring('Rahja');
.tab.liturgies {
table {
tr {
th.background {
@include coloring('Praios');
@include coloring('Rondra');
@include coloring('Efferd');
@include coloring('Travia');
@include coloring('Boron');
@include coloring('Hesinde');
@include coloring('Firun');
@include coloring('Tsa');
@include coloring('Phex');
@include coloring('Peraine');
@include coloring('Ingerimm');
@include coloring('Rahja');
tr {
th.background {
&::before {
position: absolute;
content: '';
background-image: url("../assets/velvet_strip.png");
background-repeat: repeat-y;
background-size: cover;
width: 86px;
height: 100%;
top: 45px;
left: 12px;
}
&::after { /* for tinting the texture */
content: "";
position: absolute;
width: 86px;
height: 100%;
top: 45px;
left: 12px;
}
}
}
.banner-top {
position: relative;
width: 90px;
img {
position: absolute;
top: 2px;
left: 1px;
width: 90px;
height: 90px;
border: 0;
z-index: 1;
}
&::after {
z-index: 0;
border-width: 0 4px 0 4px;
//background-color: #64b;
border-style: solid;
position: absolute;
content: "";
left: -2px;
top: 45px;
bottom: 0;
width: 94px;
}
&::before {
position: absolute;
border-radius: 45px;
height: 94px;
width: 94px;
content: '';
background-image: url("../assets/velvet_strip.png");
background-repeat: repeat-y;
background-size: cover;
width: 86px;
height: 100%;
top: 45px;
left: 12px;
}
&::after { /* for tinting the texture */
content: "";
position: absolute;
width: 86px;
height: 100%;
top: 45px;
left: 12px;
left: -2px;
right: -2px;
top: 0;
border-width: 4px;
border-style: solid;
z-index: 2;
}
}
}
.banner-top {
position: relative;
width: 90px;
img {
position: absolute;
top: 2px;
left: 1px;
width: 90px;
height: 90px;
border: 0;
z-index: 1;
}
&::after {
z-index: 0;
.banner-mid {
position: relative;
border-width: 0 4px 0 4px;
//background-color: #64b;
border-style: solid;
position: absolute;
content: "";
left: -2px;
top: 45px;
bottom: 0;
width: 94px;
width: 90px;
div {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
display: flex;
justify-content: center;
align-items: center;
div.rank-label {
position: absolute;
left: 2px;
right: 2px;
top: 0;
bottom: 0;
border-bottom: 2px solid black;
color: gold;
text-shadow: 2px 2px 1px black;
}
}
}
&::before {
position: absolute;
border-radius: 45px;
height: 94px;
width: 94px;
content: '';
left: -2px;
right: -2px;
top: 0;
.banner-bot {
position: relative;
border-width: 4px;
border-style: solid;
z-index: 2;
width: 90px;
height: 12px;
}
}
.banner-mid {
position: relative;
border-width: 0 4px 0 4px;
//background-color: #64b;
border-style: solid;
width: 90px;
.liturgy.rollable {
width: 24px;
div {
position: absolute;
top: 0;
left: 0;
bottom: 0;
right: 0;
display: flex;
justify-content: center;
align-items: center;
svg {
$color: #e4de61;
width: 24px;
height: 24px;
top: 1px;
z-index: 1;
position: relative;
div.rank-label {
position: absolute;
left: 2px;
right: 2px;
top: 0;
bottom: 0;
border-bottom: 2px solid black;
color: gold;
text-shadow: 2px 2px 1px black;
.border {
fill: #0000;
}
.center {
fill: $color;
stroke: colour.$rollable-die-border-color;
}
.topleft {
fill: color.adjust($color, $lightness: numbers.$lighter_factor);
stroke: colour.$rollable-die-border-color;
}
.bottomleft {
fill: color.adjust($color, $lightness: numbers.$lightest_factor);
stroke: colour.$rollable-die-border-color;
}
.topright {
fill: color.adjust($color, $lightness: numbers.$darken_factor);
stroke: colour.$rollable-die-border-color;
}
.bottomright, .bottom {
fill: color.adjust($color, $lightness: numbers.$darkest_factor);
stroke: colour.$rollable-die-border-color;
}
}
}
.banner-bot {
position: relative;
border-width: 4px;
border-style: solid;
width: 90px;
height: 12px;
.clickable:hover {
text-shadow: 0 0 10px rgb(255 0 0);
}
}
.liturgy.rollable {
width: 24px;
svg {
$color: #e4de61;
width: 24px;
height: 24px;
top: 1px;
z-index: 1;
position: relative;
.border {
fill: #0000;
}
.center {
fill: $color;
stroke: colour.$rollable-die-border-color;
}
.topleft {
fill: color.adjust($color, $lightness: numbers.$lighter_factor);
stroke: colour.$rollable-die-border-color;
}
.bottomleft {
fill: color.adjust($color, $lightness: numbers.$lightest_factor);
stroke: colour.$rollable-die-border-color;
}
.topright {
fill: color.adjust($color, $lightness: numbers.$darken_factor);
stroke: colour.$rollable-die-border-color;
}
.bottomright, .bottom {
fill: color.adjust($color, $lightness: numbers.$darkest_factor);
stroke: colour.$rollable-die-border-color;
}
}
}
.clickable:hover {
text-shadow: 0 0 10px rgb(255 0 0);
}
}

View File

@ -2,25 +2,27 @@
@use "./_numbers";
@use "sass:color";
.player-action {
.dsa41.sheet {
.player-action {
display: inline-block;
width: 120px;
height: 80px;
float: left;
margin: 0 8px 8px 0;
display: inline-block;
width: 120px;
height: 80px;
float: left;
margin: 0 8px 8px 0;
border: 1px solid #333;
background-color: color.scale(colours.$default-action, $alpha: 20%);
color: colours.$default-action-color;
border-radius: 4px;
box-shadow: numbers.$pill-box-inset numbers.$pill-box-inset numbers.$pill-box-blur-radius colours.$pill-box-shadow;
border: 1px solid #333;
background-color: color.scale(colours.$default-action, $alpha: 20%);
color: colours.$default-action-color;
border-radius: 4px;
box-shadow: numbers.$pill-box-inset numbers.$pill-box-inset numbers.$pill-box-blur-radius colours.$pill-box-shadow;
&.special-ability {
background-color: color.scale(colours.$special-action, $alpha: 20%);
color: colours.$special-action-color;
&.special-ability {
background-color: color.scale(colours.$special-action, $alpha: 20%);
color: colours.$special-action-color;
}
}
}

View File

@ -1,3 +1,7 @@
.editor.prosemirror.active, .editor.prosemirror.inactive {
flex: 1;
.dsa41.sheet {
.editor.prosemirror.active, .editor.prosemirror.inactive {
flex: 1;
}
}

View File

@ -1,4 +1,4 @@
.sheet.item.skill {
.dsa41.sheet.item.skill {
.meta-details {

View File

@ -44,61 +44,62 @@
}
}
// Tabs v2
// Tabs v2
.sheet-tabs {
.sheet-tabs {
position: relative;
display: flow;
border-top: unset;
border-bottom: unset;
margin-bottom: 0;
position: relative;
display: flow;
border-top: unset;
border-bottom: unset;
margin-bottom: 0;
a[data-action="tab"] {
a[data-action="tab"] {
background-color: colours.$tab-inactive-background-color;
display: inline-block;
height: 32px;
line-height: 32px;
vertical-align: middle;
padding: 0 16px;
span {
}
&.active {
border-left: numbers.$tab-border-width solid colours.$tab-border-color;
border-top: numbers.$tab-border-width solid colours.$tab-border-color;
border-right: numbers.$tab-border-width solid colours.$tab-border-color;
border-bottom: 0;
top: numbers.$tab-border-width*2;
background: assets.$tab-background;
position: relative;
z-index: 2;
background-color: colours.$tab-inactive-background-color;
display: inline-block;
height: 32px;
line-height: 32px;
vertical-align: middle;
padding: 0 16px;
span {
}
&.active {
border-left: numbers.$tab-border-width solid colours.$tab-border-color;
border-top: numbers.$tab-border-width solid colours.$tab-border-color;
border-right: numbers.$tab-border-width solid colours.$tab-border-color;
border-bottom: 0;
top: numbers.$tab-border-width*2;
background: assets.$tab-background;
position: relative;
z-index: 2;
span {
}
}
}
}
}
section.tab {
border: numbers.$tab-border-width solid colours.$tab-border-color;
background: assets.$tab-pane-background;
flex: 1;
section.tab {
border: numbers.$tab-border-width solid colours.$tab-border-color;
background: assets.$tab-pane-background;
flex: 1;
& > div {
display: flex;
flex-direction: column;
height: 100%;
gap: 8px;
padding: 8px;
& > div {
display: flex;
flex-direction: column;
height: 100%;
gap: 8px;
padding: 8px;
}
}
}

View File

@ -0,0 +1,24 @@
<div class="active-effect">
<div class="header">
<img class="img" src="{{img}}" data-action="editImage" data-edit="img" alt="{{name}}" title="{{name}}"/>
<input type="text" name="name" value="{{name}}"/>
<button class="editEffects" data-id="{{this.effectId}}" data-action="openEffect">
<i class="fas fa-pencil-alt"></i>
</button>
</div>
<div class="meta">
<label>Spielleiter Hinweise</label>
<prose-mirror
name="system.notes"
button="false"
editable="{{editable}}"
toggled="true"
value="{{system.notes}}">
{{{notes}}}
</prose-mirror>
</div>
</div>

View File

@ -1,20 +0,0 @@
<form class="{{cssClass}} {{item.type}} flexcol" autocomplete="off">
<div class="active-effect">
<div class="header">
<img src="{{item.img}}" data-edit="img" title="{{item.name}}"/>
<input type="text" name="actor.name" value="{{item.name}}"/>
<button class="editEffects" data-id="{{this.effectId}}" data-operation="editActiveEffect">
<i class="fas fa-pencil-alt"></i>
</button>
</div>
<div class="meta">
<label>Spielleiter Hinweise</label>
{{editor item.system.notes target="system.notes" button=true owner=owner editable=editable}}
</div>
</div>
</form>