diff --git a/module.json b/module.json new file mode 100644 index 0000000..6a27d6b --- /dev/null +++ b/module.json @@ -0,0 +1,14 @@ +{ + "name": "journal-links", + "title": "Journal Links", + "description": "See relationships between journal entries", + "version": "0.1.0", + "author": "dconley", + "esmodules": ["./scripts/index.js"], + "styles": ["./styles.css"], + "packs": [], + "minimumCoreVersion": "0.6.6", + "compatibleCoreVersion": "0.6.6", + "manifest": "https://raw.githubusercontent.com/moo-man/FVTT-DD-Import/master/module.json", + "download": "https://github.com/moo-man/FVTT-DD-Import/archive/master.zip" +} diff --git a/scripts/index.js b/scripts/index.js new file mode 100644 index 0000000..8b579b1 --- /dev/null +++ b/scripts/index.js @@ -0,0 +1,28 @@ +import { JournalLink } from './journallink.js'; +//import { JournalLinkSettings } from './settings.js'; + +const MODULE_NAME = 'journal-link'; +const NAME = 'Journal Link'; +const SETTINGS_NAME = 'journalLinkSettings'; + +Hooks.on("init", () => { + console.log('journal-link | initializing'); + let modulename = MODULE_NAME; + game.settings.register(MODULE_NAME, 'test-setting', { + name : 'Rebuild links on journal save', + scope: 'world', + config: true, + type: Boolean, + default: true + }); + + game.JournalLink = new JournalLink(); +}); + +Hooks.on('updateJournalEntry', (args) => game.JournalLink && game.JournalLink.updateJournalEntry(args)); +Hooks.on('renderJournalSheet', (sheet, html, data) => game.JournalLink && game.JournalLink.includeLinks(sheet, html, data)); +// updateItem +// updateActor +// roll tables have no context of this stuff +// renderActorSheet (is that generic enough?) +// renderItemSheet diff --git a/scripts/journallink.js b/scripts/journallink.js new file mode 100644 index 0000000..6d651fb --- /dev/null +++ b/scripts/journallink.js @@ -0,0 +1,126 @@ +export class JournalLink { + re = /@(\w+)\[(\w+)\]/g; + + entityMap = { + 'JournalEntry': 'journal', + 'Actor': 'actors', + 'Item': 'items', + 'RollTable': 'tables' + }; + + updateJournalEntry({ data }) { + this.update(data, 'JournalEntry'); + } + + // TODO is the lack of async/await here going to bite me? + update(data, entityType) { + console.log('journal-links | updating ' + entityType + ' ' + data.name); + + let references = this.references(data.content); + let existing = (data.flags['journal-links'] && data.flags['journal-links']['references']) || {}; + + let updated = {}; + + for (let reference of references) { + if (!updated[reference.type]) + updated[reference.type] = []; + // if we've linked something multiple times in this entity + if (updated[reference.type].includes(reference.id)) + continue + updated[reference.type].push(reference.id); + + let existingOfType = existing[reference.type] || []; + if (existingOfType.includes(reference.id)) + continue; + + let referenced = game[this.entityMap[reference.type]].get(reference.id); + let links = referenced.getFlag('journal-links', 'referencedBy') || {}; + let linksOfType = links[entityType] || []; + linksOfType.push(data._id); + + links[entityType] = linksOfType; + referenced.setFlag('journal-links', 'referencedBy', links); + } + + for (const [type, values] of Object.entries(existing)) { + let current = updated[type]; + for (let outdated of values.filter(v => !current.includes(v))) { + let entity = game[this.entityMap[type]].get(outdated); + + let links = entity.getFlag('journal-links', 'referencedBy'); + let linksOfType = links[type]; + linksOfType.splice(linksOfType.indexOf(data._id), 1); + + if (linksOfType.length) + links[type] = linksOfType; + else + delete links[type]; + entity.setFlag('journal-links', 'referencedBy', links); + } + }; + + game[this.entityMap[entityType]].get(data._id).setFlag('journal-links', 'references', updated); + } + + includeLinks(sheet, html, data) { + let links = data.entity.flags && data.entity.flags['journal-links'] && data.entity.flags['journal-links']['referencedBy'] || {}; + if (Object.keys(links).length === 0) + return; + + console.log('journal-links | appending links to ' + data.entity.name); + let element = html.find(".editor-content"); + if (element.length === 0) + return; + + let linksDiv = $('
'); + linksDiv.append($('