Compare commits
6 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
6b3ec6517f
|
|||
|
3a4d5f8fae
|
|||
|
398163df18
|
|||
|
3295b9d77e
|
|||
|
3fd8dd9650
|
|||
|
acc7cc58ec
|
1
.gitignore
vendored
1
.gitignore
vendored
@@ -1,2 +1,3 @@
|
|||||||
src/vendor/
|
src/vendor/
|
||||||
dist
|
dist
|
||||||
|
*.code-workspace
|
||||||
21
LICENSE.TXT
Normal file
21
LICENSE.TXT
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2020 Foundry Network
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
||||||
59
README.md
Normal file
59
README.md
Normal file
@@ -0,0 +1,59 @@
|
|||||||
|
# Session Title Suggestions for FoundryVTT
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
This FoundryVTT module allows players to suggest titles for the session, similar to how podcast titles are suggested. In my own sessions, I record every session's audio and make it into a podcast. Many of my favorite podcasts use a random, funny, out-of-context quote from the episode for the title. Inspired by this, I created this module so players can suggest titles and the GM can list them all and choose the best one. Players can use the `/title` or `/t` command to suggest a title. A GM or trusted player can use the `/titles` or `/ts` command to get a list of all the suggestions for the most recent day's session.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Players can suggest session titles using the `/title`, `/t`, or `t/` command.
|
||||||
|
- GMs or trusted players can view all suggested titles for the most recent session using the `/titles` or `/ts` command.
|
||||||
|
|
||||||
|
## Requirements
|
||||||
|
|
||||||
|
This module requires the Chat Commander module to be installed and enabled. You can find it [here](https://gitlab.com/woodentavern/foundryvtt-chat-command-lib).
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
1. Open FoundryVTT and go to the "Add-on Modules" tab in the "Configuration and Setup" menu.
|
||||||
|
2. Click on "Install Module".
|
||||||
|
3. In the "Manifest URL" field, paste the following URL: `[your-module-manifest-url]`.
|
||||||
|
4. Click "Install" and wait for the installation to complete.
|
||||||
|
5. Enable the module in your game settings.
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
### Suggesting a Title
|
||||||
|
|
||||||
|
Players can suggest a title for the current session by typing one of the following commands in the chat:
|
||||||
|
|
||||||
|
`/title [Your Suggested Title]`
|
||||||
|
`/t [Your Suggested Title]`
|
||||||
|
|
||||||
|
Example:
|
||||||
|
`/title The Great Heist`
|
||||||
|
|
||||||
|
### Viewing Suggested Titles
|
||||||
|
|
||||||
|
GMs or trusted players can view all the suggested titles for the most recent session by typing one of the following commands in the chat:
|
||||||
|
|
||||||
|
`/titles`
|
||||||
|
`/ts`
|
||||||
|
|
||||||
|
This will display a list of all the title suggestions.
|
||||||
|
|
||||||
|
## Contributing
|
||||||
|
|
||||||
|
If you want to contribute to the development of this module, feel free to fork the repository and submit a pull request. Any contributions, such as bug fixes, feature requests, or enhancements, are welcome.
|
||||||
|
|
||||||
|
## License
|
||||||
|
|
||||||
|
This project is licensed under the MIT License. See the [LICENSE](LICENSE.TXT) file for details.
|
||||||
|
|
||||||
|
## Contact
|
||||||
|
|
||||||
|
For any questions or issues, please open an issue on this GitHub repository.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
Thank you for using the FoundryVTT Session Title Suggestions Module! Happy gaming!
|
||||||
10
src/lang/en.json
Normal file
10
src/lang/en.json
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
{
|
||||||
|
"SESSION_TITLE_SUGGESTIONS.SETTING_ROLE_HINT": "Select the minimum role required to use the /titles command.",
|
||||||
|
"SESSION_TITLE_SUGGESTIONS.SETTING_ROLE_NAME": "List Titles Command Required Role",
|
||||||
|
"SESSION_TITLE_SUGGESTIONS.INVALID_DATE": "Invalid date provided.",
|
||||||
|
"SESSION_TITLE_SUGGESTIONS.SUGGESTION_AUTOCOMPLETE_MESSAGE": "Enter your session title suggestion.",
|
||||||
|
"SESSION_TITLE_SUGGESTIONS.SUGGESTION_LIST_COMMAND_DESCRIPTION": "List all title suggestions for the provided date",
|
||||||
|
"SESSION_TITLE_SUGGESTIONS.SUGGESTION_COMMAND_DESCRIPTION": "Suggest a title for this session",
|
||||||
|
"SESSION_TITLE_SUGGESTIONS.SUGGESTION_FLAVOR": "suggesting a session title",
|
||||||
|
"SESSION_TITLE_SUGGESTIONS.SUGGESTION_LIST_FLAVOR": "session title suggestions"
|
||||||
|
}
|
||||||
@@ -7,13 +7,20 @@
|
|||||||
"name": "lmxsdl"
|
"name": "lmxsdl"
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"version": "0.1.2",
|
"version": "0.2",
|
||||||
"compatibility": {
|
"compatibility": {
|
||||||
"minimum": "10",
|
"minimum": "10",
|
||||||
"verified": "11"
|
"verified": "11"
|
||||||
},
|
},
|
||||||
"download": "https://gitea.ascorrea.com/asc/asc-session-title-suggestions/releases/download/0.1.2/asc-session-title-suggestions-0.1.2.zip",
|
"languages": [
|
||||||
"manifest":"https://gitea.ascorrea.com/asc/asc-session-title-suggestions/raw/branch/master/src/module.json",
|
{
|
||||||
|
"lang": "en",
|
||||||
|
"name": "English",
|
||||||
|
"path": "lang/en.json"
|
||||||
|
}
|
||||||
|
],
|
||||||
|
"download": "https://gitea.ascorrea.com/asc/asc-session-title-suggestions/releases/download/0.2/module.zip",
|
||||||
|
"manifest": "https://gitea.ascorrea.com/asc/asc-session-title-suggestions/releases/download/latest/module.json",
|
||||||
"scripts": [
|
"scripts": [
|
||||||
"scripts/main.js"
|
"scripts/main.js"
|
||||||
],
|
],
|
||||||
|
|||||||
@@ -24,12 +24,11 @@ function registerClipboardCopyButton() {
|
|||||||
|
|
||||||
|
|
||||||
function registerCustomChatCommands() {
|
function registerCustomChatCommands() {
|
||||||
game.chatCommands.unregister(NAME)
|
|
||||||
game.chatCommands.register({
|
game.chatCommands.register({
|
||||||
name: NAME,
|
name: NAME,
|
||||||
module: "_chatcommands",
|
module: "_chatcommands",
|
||||||
aliases: ["/t", "t/"],
|
aliases: ["/t", "t/"],
|
||||||
description: "Suggest a title for this episode",
|
description: game.i18n.localize("SESSION_TITLE_SUGGESTIONS.SUGGESTION_COMMAND_DESCRIPTION"),
|
||||||
icon: '<i class="fa-solid fa-podcast"></i>',
|
icon: '<i class="fa-solid fa-podcast"></i>',
|
||||||
requiredRole: "NONE",
|
requiredRole: "NONE",
|
||||||
callback: async (chat, parameters, messageData) => {
|
callback: async (chat, parameters, messageData) => {
|
||||||
@@ -40,55 +39,85 @@ function registerCustomChatCommands() {
|
|||||||
newMessageData.flags = {session_title_suggestion: titleSuggestion}
|
newMessageData.flags = {session_title_suggestion: titleSuggestion}
|
||||||
return newMessageData;
|
return newMessageData;
|
||||||
},
|
},
|
||||||
autocompleteCallback: (menu, alias, parameters) => [game.chatCommands.createInfoElement("Enter a message.")],
|
autocompleteCallback: (menu, alias, parameters) => [
|
||||||
|
game.chatCommands.createInfoElement(game.i18n.localize("SESSION_TITLE_SUGGESTIONS.SUGGESTION_AUTOCOMPLETE_MESSAGE"))
|
||||||
|
],
|
||||||
closeOnComplete: true
|
closeOnComplete: true
|
||||||
});
|
}, true);
|
||||||
|
|
||||||
game.chatCommands.unregister(NAME+"s")
|
|
||||||
game.chatCommands.register({
|
game.chatCommands.register({
|
||||||
name: NAME+"s",
|
name: NAME+"s",
|
||||||
module: "_chatcommands",
|
module: "_chatcommands",
|
||||||
aliases: ["/ts"],
|
aliases: ["/ts"],
|
||||||
description: "List all titles for the most recent episode",
|
description: game.i18n.localize("SESSION_TITLE_SUGGESTIONS.SUGGESTION_LIST_COMMAND_DESCRIPTION"),
|
||||||
icon: '<i class="fa-solid fa-podcast"></i>',
|
icon: '<i class="fa-solid fa-podcast"></i>',
|
||||||
requiredRole: "TRUSTED",
|
requiredRole: game.settings.get("asc-session-title-suggestions", "titleListCommandRole"),
|
||||||
callback: async (chat, parameters, messageData) => {
|
callback: async (chat, parameters, messageData) => {
|
||||||
const newMessageData = {}
|
const newMessageData = {}
|
||||||
const suggestions = game.messages.filter(m => {
|
const suggestions = game.messages.filter(m => {
|
||||||
return m.flags.session_title_suggestion
|
return m.flags.session_title_suggestion
|
||||||
})
|
})
|
||||||
|
let selected_message_date
|
||||||
const last_message_date = new Date(suggestions[suggestions.length-1].timestamp)
|
if (!parameters) {
|
||||||
|
selected_message_date = new Date(suggestions[suggestions.length-1].timestamp)
|
||||||
|
|
||||||
|
} else {
|
||||||
|
const epoch_date = Date.parse(parameters)
|
||||||
|
if (Number.isNaN(epoch_date)){
|
||||||
|
ui.notifications.error(`${game.i18n.localize("SESSION_TITLE_SUGGESTIONS.INVALID_DATE")} (${parameter})`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
selected_message_date = new Date(epoch_date)
|
||||||
|
}
|
||||||
const filtered_suggestions = suggestions.filter(m=>{
|
const filtered_suggestions = suggestions.filter(m=>{
|
||||||
const message_date = new Date(m.timestamp)
|
const message_date = new Date(m.timestamp)
|
||||||
return message_date.toDateString() == last_message_date.toDateString()
|
return message_date.toDateString() == selected_message_date.toDateString()
|
||||||
})
|
})
|
||||||
newMessageData.content = await renderTemplate(TEMPLATES.suggestionList.content, {messages:filtered_suggestions })
|
newMessageData.content = await renderTemplate(TEMPLATES.suggestionList.content, {messages:filtered_suggestions })
|
||||||
newMessageData.flavor = await renderTemplate(TEMPLATES.suggestionList.flavor, {date:last_message_date.toDateString()})
|
newMessageData.flavor = await renderTemplate(TEMPLATES.suggestionList.flavor, {date:selected_message_date.toDateString()})
|
||||||
return newMessageData;
|
return newMessageData;
|
||||||
},
|
},
|
||||||
autocompleteCallback: (menu, alias, parameters) => [game.chatCommands.createInfoElement("Enter a message.")],
|
autocompleteCallback: (menu, alias, parameters) => {
|
||||||
|
const suggestions = game.messages.filter(m => {
|
||||||
|
return m.flags.session_title_suggestion
|
||||||
|
})
|
||||||
|
const dates = new Set(
|
||||||
|
suggestions.map(s=>new Date(s.timestamp).toDateString())
|
||||||
|
)
|
||||||
|
const entries = [...dates].map(date=>{
|
||||||
|
return game.chatCommands.createCommandElement(`${alias} ${date}`, date)
|
||||||
|
})
|
||||||
|
|
||||||
|
entries.length = Math.min(entries.length, menu.maxEntries);
|
||||||
|
return entries;
|
||||||
|
},
|
||||||
closeOnComplete: true
|
closeOnComplete: true
|
||||||
});
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
console.log("Hello World! This code runs immediately when the file is loaded.");
|
|
||||||
|
|
||||||
Hooks.on("init", function() {
|
Hooks.on("init", function() {
|
||||||
//This code runs once the Foundry VTT software begins its initialization workflow
|
//This code runs once the Foundry VTT software begins its initialization workflow
|
||||||
registerCustomChatCommands();
|
|
||||||
registerClipboardCopyButton();
|
registerClipboardCopyButton();
|
||||||
loadTemplates(flavor_template_path)
|
Object.values(TEMPLATES.suggestion).forEach((template_path)=>loadTemplates(template_path))
|
||||||
Object.values(TEMPLATES.suggestion).forEach((template_path)=>{
|
Object.values(TEMPLATES.suggestionList).forEach((template_path)=>loadTemplates(template_path))
|
||||||
loadTemplates(template_path)
|
game.settings.register("asc-session-title-suggestions", "titleListCommandRole", {
|
||||||
}
|
name: game.i18n.localize("SESSION_TITLE_SUGGESTIONS.SETTING_ROLE_NAME"),
|
||||||
)
|
scope: "world",
|
||||||
Object.values(TEMPLATES.suggestionList).forEach((template_path)=>{
|
config: true,
|
||||||
loadTemplates(template_path)
|
type: String,
|
||||||
}
|
default: "TRUSTED",
|
||||||
)
|
requiresReload: true,
|
||||||
|
choices: {
|
||||||
|
"PLAYER": game.i18n.localize("USER.RolePlayer"),
|
||||||
|
"TRUSTED": game.i18n.localize("USER.RoleTrusted"),
|
||||||
|
"ASSISTANT": game.i18n.localize("USER.RoleAssistant"),
|
||||||
|
"GAMEMASTER": game.i18n.localize("USER.RoleGamemaster")
|
||||||
|
},
|
||||||
|
hint: game.i18n.localize("SESSION_TITLE_SUGGESTIONS.SETTING_ROLE_HINT")
|
||||||
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
Hooks.on("ready", function() {
|
Hooks.on("ready", function() {
|
||||||
//This code runs once core initialization is ready and game data is available.
|
//This code runs once core initialization is ready and game data is available.
|
||||||
|
registerCustomChatCommands();
|
||||||
});
|
});
|
||||||
@@ -1 +1 @@
|
|||||||
<i class="fa-solid fa-podcast"></i> suggesting an session title...
|
<i class="fa-solid fa-podcast"></i> {{localize 'SESSION_TITLE_SUGGESTIONS.SUGGESTION_FLAVOR'}}...
|
||||||
@@ -1 +1 @@
|
|||||||
<i class="fa-solid fa-podcast"></i> title suggestions ({{date}}):
|
<i class="fa-solid fa-podcast"></i> {{localize "SESSION_TITLE_SUGGESTIONS.SUGGESTION_LIST_FLAVOR"}} ({{date}}):
|
||||||
Reference in New Issue
Block a user