Skip to content

Commit

Permalink
initial commit
Browse files Browse the repository at this point in the history
  • Loading branch information
Sigafoos committed Sep 2, 2020
0 parents commit b8b223f
Show file tree
Hide file tree
Showing 5 changed files with 173 additions and 0 deletions.
14 changes: 14 additions & 0 deletions module.json
Original file line number Diff line number Diff line change
@@ -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"
}
28 changes: 28 additions & 0 deletions scripts/index.js
Original file line number Diff line number Diff line change
@@ -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
126 changes: 126 additions & 0 deletions scripts/journallink.js
Original file line number Diff line number Diff line change
@@ -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 = $('<div class="journal-links"></div>');
linksDiv.append($('<h1>Linked from</h1>'));
for (const [type, values] of Object.entries(links)) {
if (values.length === 0)
continue;

linksDiv.append($('<h2>' + type + '</h2>'));
let linksList = $('<ul></ul>');
for (let value of values) {
let entity = game[this.entityMap[type]].get(value);
let link = $('<a class="entity-link" draggable="true"></a>');
link.attr('data-entity', type);
link.attr('data-id', entity._id);

let icon = 'fas ';
switch (type) {
case 'JournalEntry':
icon += 'fa-book-open';
break;
case 'Actor':
icon += 'fa-user';
break;
case 'Item':
icon += 'fa-suitcase';
break;
case 'RollTable':
icon == 'fa-th-list';
break;
}
link.append($('<i class="' + icon + '"></i>'));
link.append(' ' + entity.name);

let li = $('<li></li>');
li.append(link);
linksList.append(li);
}
linksDiv.append(linksList);
}
element.append(linksDiv);
}

references(text) {
return Array.from(text.matchAll(this.re)).map(
m => {
return {
type: m[1],
id: m[2]
}
}
);
}
}
5 changes: 5 additions & 0 deletions scripts/settings.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
export class JournalSyncSettings extends FormApplication {
static init() {
game.settings.registerMenu('journal-sync', '
}
}
Empty file added styles.css
Empty file.

0 comments on commit b8b223f

Please sign in to comment.