ianfab / fairyground

playground for Fairy-Stockfish in the browser
https://fairyground.vercel.app/
GNU General Public License v3.0
20 stars 5 forks source link

Support selection of image per piece #5

Closed ianfab closed 4 months ago

ianfab commented 2 years ago

Allow to customize themes by selecting from a predefined set of images (at least) for custom variants in order to disambiguate which piece is referred to by a given letter, either via the variants.ini or a UI selection.

dpldgr commented 9 months ago

@ianfab has this basically been completed now that PR #26 has been merged? I've been able to integrate the correct custom graphics for my variants in my development environment since this merge.

ianfab commented 9 months ago

Features are meant to be usable by the end user, not just developers. So what this issue means is to have flexibility in choice of piece representation similar as #28, but it does not necessarily have to go the WinBoard direction of using the pieceToCharTable, there might also be different solutions.

yjf2002ghty commented 9 months ago

There are some problems:

  1. Most browsers do not allow JavaScript to access client side files unless the user explicitly selects the files from the "load file" dialog. This means that each time the user open fairyground, they will have to select the theme resources manually. (Cookies, Session Storage and Local Storage that can be loaded from client without consent cannot save CSS and graphs)
  2. If the assets come from server, the user cannot change the contents. Otherwise different users can make changes that may conflict with each other and pose threat to the server security. If you deploy your project on Vercel, changing server files during runtime is not possible.

Currently the best solution that comes up to my mind is to use another web page that can select images for each pieces and save all the necessary data to an archive(probably a zip archive), and encode the archive data with BASE64 and save it in local storage. When fairyground is open, it will check local storage and use the data by decoding BASE64, extracting archive and loading the resources if it exists. But I'm not sure whether this is possible as it seems that CSS files must be loaded from server file system instead of client memory or file system.

dpldgr commented 9 months ago

Features are meant to be usable by the end user, not just developers. So what this issue means is to have flexibility in choice of piece representation similar as #28, but it does not necessarily have to go the WinBoard direction of using the pieceToCharTable, there might also be different solutions.

The end user can cycle through the piece sets specified by the developer in themes.txt. As an example, I modified themes.txt to add my new letter tiles to all variants using *|letters,goldletters|, and the end user can access them by clicking on "Change pieces": Screenshot 2023-10-12 164601

If you're meaning that end users should be able to specify new graphics that they've found elsewhere, @yjf2002ghty highlights some potential issues with being able to do that on a web based project.

ianfab commented 9 months ago

To clarify what I meant by this issue, the "selection" was referring only to choosing from existing images, not uploading new ones. It is mainly to address ambiguities as discussed in #2, like archbishop vs amazon.

I am imagining that likely the best solution is that for built-in variants we use the customization via themes as implemented by yjf2002ghty, and then have some kind of user selection/customization for custom variants, whether it is via the variants.ini or selections in the UI.

PS: Sorry for lacking descriptions in most issues created by me in this repo, I just created them as reminders for myself. Now that more people than just myself read, comment, and develop on the issues in this repo I will try to be more specific.

dpldgr commented 9 months ago

PS: Sorry for lacking descriptions in most issues created by me in this repo, I just created them as reminders for myself. Now that more people than just myself read, comment, and develop on the issues in this repo I will try to be more specific.

That's no worries at all. I guess it's a common occurence for projects start off with a single developer and then start building a developer base.

To clarify what I meant by this issue, the "selection" was referring only to choosing from existing images, not uploading new ones. It is mainly to address ambiguities as discussed in #2, like archbishop vs amazon.

I am imagining that likely the best solution is that for built-in variants we use the customization via themes as implemented by yjf2002ghty, and then have some kind of user selection/customization for custom variants, whether it is via the variants.ini or selections in the UI.

I think I'm starting to understand the issue a bit more myself. Obviously for the built-in variants it's possible to know what all of the pieces do in advance. I've been stuck in "custom variant developer mode" so I was thinking of the issues that had arisen for me. There might be a few different ways of overriding specific pieces in specific variants such as the amazon vs archbishop case. I may also know a way of linking externally to graphics for custom variants.

dpldgr commented 9 months ago

Ok, I think I have figured out how to do it! Adding a link to a variant specific style sheet allows you to override the piece set graphics:

<link rel="stylesheet" href="./assets/theme-piece-merida.css">
<link rel="stylesheet" href="./assets/theme-piece-cburnett.css">
<link rel="stylesheet" href="./assets/theme-variant-capablanca.css">

Then in theme-variant-capablanca.css:

.cburnett .cg-wrap piece.a-piece.white {
  background-image: url('images/pieces/cburnett/capablanca/Chess_alt45.svg');
}
.cburnett .cg-wrap piece.a-piece.black {
  background-image: url('images/pieces/cburnett/capablanca/Chess_adt45.svg');
}
.merida .cg-wrap piece.a-piece.white {
  background-image: url('images/pieces/merida/capablanca/wA.svg');
}
.merida .cg-wrap piece.a-piece.black {
  background-image: url('images/pieces/merida/capablanca/bA.svg');
}

Here's an example, with the "A" piece replaced by randomly selected images.

No variant specific link added and merida selected: image With <link rel="stylesheet" href="./assets/theme-variant-capablanca.css"> added and merida selected: image No variant specific link added added and cburnettselected: image With <link rel="stylesheet" href="./assets/theme-variant-capablanca.css"> added and cburnettselected: image

dpldgr commented 9 months ago

There are some problems:

  1. Most browsers do not allow JavaScript to access client side files unless the user explicitly selects the files from the "load file" dialog. This means that each time the user open fairyground, they will have to select the theme resources manually. (Cookies, Session Storage and Local Storage that can be loaded from client without consent cannot save CSS and graphs)
  2. If the assets come from server, the user cannot change the contents. Otherwise different users can make changes that may conflict with each other and pose threat to the server security. If you deploy your project on Vercel, changing server files during runtime is not possible.

Currently the best solution that comes up to my mind is to use another web page that can select images for each pieces and save all the necessary data to an archive(probably a zip archive), and encode the archive data with BASE64 and save it in local storage. When fairyground is open, it will check local storage and use the data by decoding BASE64, extracting archive and loading the resources if it exists. But I'm not sure whether this is possible as it seems that CSS files must be loaded from server file system instead of client memory or file system.

I have had a bit of an exploration on this. Here's what I've found so far:

I'm currently working on:

Yet to explore:

yjf2002ghty commented 9 months ago

Yet to explore:

  • Using localStorage to more permanently store the above.

A better way to store these files would be IndexedDB. It's much more powerful than Local Storage.

https://developer.chrome.com/docs/devtools/storage/indexeddb/

dpldgr commented 9 months ago

Yet to explore:

  • Using localStorage to more permanently store the above.

A better way to store these files would be IndexedDB. It's much more powerful than Local Storage.

https://developer.chrome.com/docs/devtools/storage/indexeddb/

Thanks for the link. I have seen IndexedDB mentioned somewhere, but one potential issue I noticed (at least in the past) is it couldn't store binary blobs. I don't know if that's still the case (hopefully it's not) as I haven't had to chance to do much research on persistent storage yet. It's probably not a deal breaker either way, because you could always store things base64 encoded (as you mentioned previously), but it's nice to store things efficiently where possible.

EDIT: just looking at some of the preliminary research I did a week or so ago, PouchDB seems like a good candidate for further exploration.

ianfab commented 4 months ago

Closed in #49