Xbozon / storyteller

A small modification that allows you to present the story in the game as an open book.
Apache License 2.0
16 stars 9 forks source link

Star Wars datapad theme #37

Open Carl-Hugo opened 1 year ago

Carl-Hugo commented 1 year ago

Hi, I really like this plugin; having an image or text never made sense to me while having both was way better. This led me to want a version for Star Wars, so I built Storyteller Star Wars theme for Foundry VTT on top of Storyteller (a Star Wars datapad theme), which was fairly simple. The hardest part was figuring out the Foundry pieces and how to build my CI/CD pipeline (my first time playing with Foundry's APIs).

Anyway, I'm dropping this note here to let you know, and maybe someone else could leverage the same pattern I did to extend Storyteller even more with their own theme.

Preview

Storyteller Star Wars theme for Foundry VTT datapad

Xbozon commented 1 year ago

@Carl-Hugo It's amazing! I'm very glad you liked my mod, your version turned out very organic. You did a very good job adding it as an addon rather than a fork. This way it will be much easier to get fresh updates.

Xbozon commented 1 year ago

I plan to update the style registration system, but I will write to you so you can quickly update your mod.

Carl-Hugo commented 1 year ago

I plan to update the style registration system, but I will write to you so you can quickly update your mod.

Thanks, please do; appreciated.

@Carl-Hugo It's amazing! I'm very glad you liked my mod, your version turned out very organic. You did a very good job adding it as an addon rather than a fork. This way it will be much easier to get fresh updates.

Tbh, I started by forking the project to analyze how it worked (it was my first Foundry module/code), then I refactored the theme out of it as I did not want to maintain a fork of Storyteller. Then I cleaned up the code as much as possible, added support for continuous delivery so every commit pushed to main gets released, and here we are.

Carl-Hugo commented 1 year ago

Any plan on getting the storyteller.theme setting back @Xbozon, whether it is the original or a new system? Would you be open to a contribution? Any idea about the design of the new system?

Meanwhile, here is an idea about a potential API for the new registration system:

game.StoryTeller.themes.all: { id: string, name: string, cssClass: string }[];
game.StoryTeller.themes.getById(id: string): { id: string, name: string, cssClass: string };
game.StoryTeller.themes.add({ id: string, name: string, cssClass: string });
game.StoryTeller.themes.remove(id: string); // Not sure this is useful, but why not

So themes could register themselves like this:

Hooks.on('init', () => game.StoryTeller.themes.add({ 
    id: 'starwars', 
    name: 'Star Wars', 
    cssClass: 'star-wars-storyteller-sheet' 
}));

And ensure a theme registers its CSS in the module.json file and specify it depends on storyteller so they load in the correct order (ensure game.StoryTeller.themes is defined).

Xbozon commented 1 year ago

@Carl-Hugo Yes, of course. I definitely plan to be able to register themes using the api. I had to suspend all work on my modules because of the incredible workload, I'm combining work and study in another country. I might be able to do something over the New Year holidays, but fixing bugs has priority.

As for theme selection, it used to be just adding a class to the log div, which worked globally. Since the last update, each theme requires its own description file, inherited from https://github.com/Xbozon/storyteller/blob/main/sheets/story-sheet.js

For this reason, the api will be a bit more complicated. For now, I can only recommend that you use an older version to support your theme.

Carl-Hugo commented 1 year ago

I'm combining work and study

Of course, this is not a priority, don't worry about it, and good luck with your study!

As for theme selection, it used to be just adding a class to the log div, which worked globally.

I remember, that's why I mentioned cssClass in my API design 😉

Since the last update, each theme requires its own description file

This is strange... If I can guess, this probably has something to do with defaultOptions, maybe the loaded sequence vs. the init hook?

For this reason, the api will be a bit more complicated.

I'll try to find time, fork the repo, and experiment a little with it; I'll share back my findings.

For now, I can only recommend that you use an older version to support your theme.

I already updated to Foundry v10...

Carl-Hugo commented 1 year ago

I played a bit with your code @Xbozon, and the only thing you have to do to put the themes back into it is to override the getData method in your StorySheet class like this:

export class StorySheet extends JournalSheet {
    // ...
    getData(options) {
        if(options) {
            const theme = game.settings.get('storyteller', 'theme');
            if (options.classes.indexOf(theme) === -1) {
                options.classes.push(theme);
            }
        }
        return super.getData(options);
    }
    // ...
}

And, of course, add the theme setting back in the registerSettings function, in the main.js file, like this:

    game.settings.register('storyteller', 'theme', {
        name: game.i18n.localize('STORYTELLER.Settings.Theme'),
        hint: game.i18n.localize('STORYTELLER.Settings.ThemeHint'),
        scope: 'world',
        type: String,
        choices: {
            book: game.i18n.localize('STORYTELLER.Settings.ThemeBook'),
        },
        default: 'book',
        config: true,
    });

Hope this helps. I can also open a PR if you want.

Xbozon commented 1 year ago

@Carl-Hugo

Very sorry for the long reply, I added changes to the code to support your addon. Now you can use api to add any custom log style.

Please see an example of what I did for a demonstration: https://github.com/Xbozon/storyteller-addon-example

A system with an external class, will not only allow you to change the css style, but also change the functionality to suit your needs. For example, remove the page flip function.

This may be complicated at first glance, but I am always happy to answer your questions here or on discord.

Thank you!

Carl-Hugo commented 1 year ago

Hey @Xbozon!

No worries for the delay, life > free open-source hobby modules 😉 (I was running my own version of StoryTeller locally anyway).

I understand the flexibility potential of your change, and it is okay if this is your preferred way, I don't mind at all you closed my PR. However, it seems to require writing (or copying & pasting) a lot of boilerplate code to make small changes. Maybe I'm wrong, I'll explore a bit before jumping to any conclusion and see what Foundry allows me to reuse and how lighter a theme can become (compared to your example). To be continued...

Before that continuation, if you are interested, here is some background about me: I'm an experienced software engineer/architect with almost 20 years of experience and 2 published books about software/technical architecture. However, I'm new to Foundry VTT modules development, so I'm not familiar with all the Foundry VTT APIs and such (and they seem to change often with limited to no backward compatibility). I also taught web programming to multiple cohorts, many years ago.

That said, if I want to take you on your help offer, what Discord server are you referring to?


Meanwhile, to ensure the "addon sheets" load in the correct order, you should add the following in its module.json file and replace the verified version number by the correct one.

"relationships": {
        "systems": [],
        "requires": [
            {
                "id": "storyteller",
                "type": "module",
                "manifest": "https://raw.githubusercontent.com/Xbozon/storyteller/main/module.json",
                "compatibility": {
                    "verified": "1.1.0"
                }
            }
        ]
    }

That change could also lead to removing the if (game.StoryTeller !== undefined) check since StoryTeller should be loaded; dependent modules get loaded first and users get prompted about them when enabling them.

I hope this last bit helps

Xbozon commented 1 year ago

@Carl-Hugo

The need to use my proposed method comes from the fact that I have added a page flip function to the journal. Since it uses a very specific html template, with the turn.js plugin, it is very difficult to disable it with just js and css, keeping the functionality for Star Wars Datapad. The solution through the addon will allow you to use any html code as markup.

Your work is impressive, I hope someday I can boast of something similar :) At the moment I am a golang developer and very bad at JavaScript, but my desire to make the players happy was higher.

As for discord, I apologize, I completely forgot that I removed it from the Readme. You can find me at Xbozon#4313

I also added the changes you suggested to the example addon. Thank you!

Carl-Hugo commented 1 year ago

@Carl-Hugo

The need to use my proposed method comes from the fact that I have added a page flip function to the journal. Since it uses a very specific html template, with the turn.js plugin, it is very difficult to disable it with just js and css, keeping the functionality for Star Wars Datapad. The solution through the addon will allow you to use any html code as markup.

True. However, I may need to write HTML now 😉 (which is fine).

Your work is impressive, I hope someday I can boast of something similar :) At the moment I am a golang developer and very bad at JavaScript, but my desire to make the players happy was higher.

Thanks. Feel free to poke me if you ever plan to write a book and want a few tips. That takes way more work than one can imagine, but it's fun and rewarding to share your knowledge with the world.

Go seems like a language in high demand that pays well these days; I'm a big C# fan but Go sounds like a good choice. Anyway, you'll most likely end up learning more than one language over the years.

As for discord, I apologize, I completely forgot that I removed it from the Readme. You can find me at Xbozon#4313

Thanks, I sent you a friend request, just in case.

I also added the changes you suggested to the example addon. Thank you!

Great.