Initial
This commit is contained in:
133
resources/app/client/core/nue.js
Normal file
133
resources/app/client/core/nue.js
Normal file
@@ -0,0 +1,133 @@
|
||||
/**
|
||||
* Responsible for managing the New User Experience workflows.
|
||||
*/
|
||||
class NewUserExperience {
|
||||
constructor() {
|
||||
Hooks.on("renderChatMessage", this._activateListeners.bind(this));
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Initialize the new user experience.
|
||||
* Currently, this generates some chat messages with hints for getting started if we detect this is a new world.
|
||||
*/
|
||||
initialize() {
|
||||
// If there are no documents, we can reasonably assume this is a new World.
|
||||
const isNewWorld = !(game.actors.size + game.scenes.size + game.items.size + game.journal.size);
|
||||
if ( !isNewWorld ) return;
|
||||
this._createInitialChatMessages();
|
||||
// noinspection JSIgnoredPromiseFromCall
|
||||
this._showNewWorldTour();
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Show chat tips for first launch.
|
||||
* @private
|
||||
*/
|
||||
_createInitialChatMessages() {
|
||||
if ( game.settings.get("core", "nue.shownTips") ) return;
|
||||
|
||||
// Get GM's
|
||||
const gms = ChatMessage.getWhisperRecipients("GM");
|
||||
|
||||
// Build Chat Messages
|
||||
const content = [`
|
||||
<h3 class="nue">${game.i18n.localize("NUE.FirstLaunchHeader")}</h3>
|
||||
<p class="nue">${game.i18n.localize("NUE.FirstLaunchBody")}</p>
|
||||
<p class="nue">${game.i18n.localize("NUE.FirstLaunchKB")}</p>
|
||||
<footer class="nue">${game.i18n.localize("NUE.FirstLaunchHint")}</footer>
|
||||
`, `
|
||||
<h3 class="nue">${game.i18n.localize("NUE.FirstLaunchInvite")}</h3>
|
||||
<p class="nue">${game.i18n.localize("NUE.FirstLaunchInviteBody")}</p>
|
||||
<p class="nue">${game.i18n.localize("NUE.FirstLaunchTroubleshooting")}</p>
|
||||
<footer class="nue">${game.i18n.localize("NUE.FirstLaunchHint")}</footer>
|
||||
`];
|
||||
const chatData = content.map(c => {
|
||||
return {
|
||||
whisper: gms,
|
||||
speaker: {alias: game.i18n.localize("Foundry Virtual Tabletop")},
|
||||
flags: {core: {nue: true, canPopout: true}},
|
||||
content: c
|
||||
};
|
||||
});
|
||||
ChatMessage.implementation.createDocuments(chatData);
|
||||
|
||||
// Store flag indicating this was shown
|
||||
game.settings.set("core", "nue.shownTips", true);
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Create a default scene for the new world.
|
||||
* @private
|
||||
*/
|
||||
async _createDefaultScene() {
|
||||
if ( !game.user.isGM ) return;
|
||||
const filePath = foundry.utils.getRoute("/nue/defaultscene/scene.json");
|
||||
const response = await foundry.utils.fetchWithTimeout(filePath, {method: "GET"});
|
||||
const json = await response.json();
|
||||
const scene = await Scene.create(json);
|
||||
await scene.activate();
|
||||
canvas.animatePan({scale: 0.7, duration: 100});
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Automatically show uncompleted Tours related to new worlds.
|
||||
* @private
|
||||
*/
|
||||
async _showNewWorldTour() {
|
||||
const tour = game.tours.get("core.welcome");
|
||||
if ( tour?.status === Tour.STATUS.UNSTARTED ) {
|
||||
await this._createDefaultScene();
|
||||
tour.start();
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Add event listeners to the chat card links.
|
||||
* @param {ChatMessage} msg The ChatMessage being rendered.
|
||||
* @param {jQuery} html The HTML content of the message.
|
||||
* @private
|
||||
*/
|
||||
_activateListeners(msg, html) {
|
||||
if ( !msg.getFlag("core", "nue") ) return;
|
||||
html.find(".nue-tab").click(this._onTabLink.bind(this));
|
||||
html.find(".nue-action").click(this._onActionLink.bind(this));
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Perform some special action triggered by clicking on a link in a NUE chat card.
|
||||
* @param {TriggeredEvent} event The click event.
|
||||
* @private
|
||||
*/
|
||||
_onActionLink(event) {
|
||||
event.preventDefault();
|
||||
const action = event.currentTarget.dataset.action;
|
||||
switch ( action ) {
|
||||
case "invite": return new InvitationLinks().render(true);
|
||||
}
|
||||
}
|
||||
|
||||
/* -------------------------------------------- */
|
||||
|
||||
/**
|
||||
* Switch to the appropriate tab when a user clicks on a link in the chat message.
|
||||
* @param {TriggeredEvent} event The click event.
|
||||
* @private
|
||||
*/
|
||||
_onTabLink(event) {
|
||||
event.preventDefault();
|
||||
const tab = event.currentTarget.dataset.tab;
|
||||
ui.sidebar.activateTab(tab);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user