0
0
mirror of https://github.com/naturalcrit/homebrewery.git synced 2026-03-22 08:58:11 +00:00

Updated with info from discussing this in gitter, might update again soon as there is more background related discussion to read.

Víctor Losada Hernández
2023-09-09 19:27:58 +02:00
parent 2b71fa9083
commit eaf778b373

@@ -1,221 +1,129 @@
Folders and Tags and Oh My!
Notes on folders
=============================
This is a scratch-pad work-in-progress of notes. Once the content settles down into something coherent it will be moved to a discussion.
This is a scratch-pad work-in-progress of notes. Once the content settles down into something coherent we may create the issue or PR.
## Previously on Github..
The feature idea of folders spawned discussions that branched into tags, and how they both interact with publishing and access.
The chat about folders has brought up many questions and doubts about how to approach the project
- https://github.com/naturalcrit/homebrewery/issues/697
> It says under the publish button that eventually published brews will be publically viewable and searchable. Is that going to be soon, or is it still a long way off?
- https://github.com/naturalcrit/homebrewery/issues/697#issuecomment-766328549
> I was just thinking about that; I have about a dozen brews that I made to help out someone in the subreddit; I've taken to giving them a title that starts with "Example:" so that they appear in one place in the list, but it'd be even better if I could dump them in an "Examples" folder where I don't actually have to look at them.
- https://github.com/naturalcrit/homebrewery/issues/758
> I've got a lot of brews, and I imagine others do as well. It would be great to be able to organize these into folders that I can drill into for specific brews. For example, I might want to have one folder for each campaign that I'm running, or one to hold my custom magic items, or another to hold my custom races and classes.
- https://github.com/naturalcrit/homebrewery/discussions/1471
> Capturing discussion/thinking from the Gitter chat today for future useL
- https://github.com/naturalcrit/homebrewery/pull/1839
> [code and UI for editing tags on brews]
- https://github.com/naturalcrit/homebrewery/issues/1842
> I know there has been talk of tagging/grouping, but in the meantime it would seem that the selected game system for a brew could be represented on the `.brewItems`
The following is an attempt to collate and untangle.
here lies a list of related issues that may contain related info, for the purpose of completeness, i will be including all important info from them as well.
## Tags vs Folders
### why?
**Folders** are primarily intended as a you-thing, to assist with keeping a big mess of brews orderly. A given folder is defined more by its members as a whole, and not so much as a shared characteristic of its members. Folders are buckets, folders are places.
Folders have been suggested for years, as a way to oganize work de-clutter the userpage, and group related documents
**Tags** are primarily intended for classifying published brews for other people, as a shared vocabulary. But you can also use tags on your private brews. Tags are tags.
## Minimum Viable Product (MVP)
As a project starter, a definition of a MVP has been set, that is a product with the minimum necessary features for it to work, and from which we can expand by adding little by little.
### Complications:
- private tags?
- brew in multiple folders? (e.g. "Social Contract")
- multi-author access .. folders are per-author basis, tags are per-brew basis
- tags on folders?
- marking sub-folders as owner-only (i.e. don't ist in public views) (good for stashing private notes)
The MVP should include:
### features
"CRUD" features: create folders, delete folders, update name and contents, and be able to read the contents.
Author-specific
Opening a link for a non-existant folder should trigger a 404
a brew should be able to be in multiple folders at once
folders can have subfolders of their own
no duplicate names for folders inside the same account
Folder should appear in the brew title inside the share and edit pages("Examples: how to make tables")
Folders should appear before any brew in the user page
## Publishing
a link should be `/user/:userId/:folderName`
Any public UI for searching by tag won't reveal links to non-published brews with those tags. They remain un-published.
All brews however are publicly viewable via their /share, /print, /edit URLs. The "published" status doesn't affect that.
(/edit urls are however getting restricted to authors-only)
We do want to facilitate sharing of folder views. That is, a user could share `/user/erics/friday-game` to his Friday Game participants; or share publicly `/user/erics/monsters` to the world (although that might be better served as /user/erics?tags=monsters).
These folders should be able to reveal unpublished brews. Or, more exactly, it should not be firstly necessary to mark each enclosed brew as published for those enclosed brews to be visible to those whom the folder has been shared to (because that would a. massively clutter up their published brews list, and b. reveal those semi-private brews outside the group to whom the folder was shared.)
OK, that seems fine .. except the folder-owner might well want to stash a few folder-relevant brews into that folder which they _don't_ want to reveal, not even to the folder-shared group. Like "BBEG's plan to deal with those meddling kids".
We might be able to do something like having a special meta-tag which basically says "Author Eyes Only". If not one of the listed authors the brew does not appear in any list, and requests return either 404, 503, or whatever. Actually, this would be useful even if folders were not a thing (currently all brews are publicly accessible, with some marked as "will appear in lists as published". This tag will work to mark the brew as "definitely don't reveal to anyone else".
### Data structure
- `__Id` (mongo specific ID field, exists wether we create it or not)
- `folderId` (nanoid, required, auto)
- `folderName` (to use in the URL) (string, required)
- `owner` (can be multiple)
- `brewIds`(shareId)
- `createdAt`
- `UpdatedAt`
### Published, Public, Hidden
Currently the "is-published" status is stored as `"published":true` .. it could be three possible values, meaning `published`, `whatever-false-means-now-as-default`, and `hidden-and-by-that-i-mean-share-link-fails`.
That way a creator can stash GM-eyes-only docs in e.g. `/user/erics/friday-game` folder.
Behind the scenes the 3 values could be `published`, `public`, and `hidden`. (Or `True`, `False`, `Null` to be backwards compatible yet maddeningly obscurantist).
## Folders as first class mongo object
- brews can be assigned to folders
These folders should be displayed in the user page of the author of such folder <!-- could be a good idea to be able to copy someone else's folder, which should only copy published brews -->, opening the folder would bring the user to another page with the content of the folder displayed as if it was a user page.
So all unpublished files will still be invisible to unauthored accounts<!--although if you are an author you still can't see an unpublished brew, that needs a fix -->, even if they are inside a publicly viewable folder.<!--we could make it so that any folder without any published brew is invisible? -->
"Yes, so the "my campaign" folder can contain a published "magic ring" document that the players can see (because they have attained said ring) and also private "magic sword" document because players have not attained it."
## Optimal Final Product
### Features:
are private folders publicly viewable?
- thumnails
- tags
- views (useless?)
- systems
- description
- brewCount
- put someone else's brews into your folder
- folders inside folders?
- move brews from folderA to folderB
- ability to hit a button to publish all brews inside
- folder password
- folder object could also have a link to a parent-folder (preferable to a list of contained-folders, to avoid loops etc)
- select via a picker UI (not by typing strings)
- store mongoids in codefenced block - store in the brew itself??
- smart and dumb folders - additional properties
- folder object could also have a link to a parent-folder (preferable to a list of contained-folders, to avoid loops etc)
- password-protected folders
- blank password, password shared, password not shared
- plausible deniability if bad password or no password (give me access or give me death aka 404)
The brew metadata panel and folder picker UI should only show the folders belonging to that user, but also maintain back-end the other user's folder assignments.
## Tags collated into categories/schemas
We do want to facilitate sharing of folder views. That is, a user could share `/user/erics/friday-game` to his Friday Game participants; or share publicly `/user/erics/monsters` to the world (although that might be better served as /user/erics?tags=monsters).
(inspiration: GMB)
### Data structure
- game system: 5e, 4e, PF1, PF2, GURPS, .. etc
- content type - map, adventure, class, item, spell, monster, location, race, npc, etc
- genre - fantasy, scifi, modern, .. ?
- licensing - OGL, MIT, PD, CC-BY-4.0, etc
- meta: guide, theme, template
- .. ?
When we do get around to tags, and categories of tags .. one such category I'm imagining would be for licensing ..
- `license:OGL`
- `license:Public Domain`
- `license:CC BY-NC 4.0`
- `license:MIT`
- `license:mixed`
- `license:custom`
etc
These various tag categories would be finite and pre-coordinated in the list of categories, and in the tag values within each category. Outside of those categories would be free form custom tags, which are limited only by what characters can be used to form them (probably `[a-zA-Z0-9_-./& ]` (i.e. reserving use of special chars for possible future use, of which `:` is one character obviously already in use).
## URLs
Brews will become access via Tags and Folders, and thus will appear in the URLs
- /edit/brewID
- /share/brewID
- /user/accountname/
- /user/accountname/foldername/
- /user/accountname/foldername/nestedfolder/
- /user/accountname/?q=string
- /user/accountname/?tags=tag1,tag2,tag3
- /user/accountname/?q=string&tags=tag1,tag2
- /user/accountname/foldername/nestedfolder/?q=string&tags=tag1,tag2
tags=tag1,tag2,tag3 -> tags match tags, exact match only
brews displayed inside folders are linked via direct brewID links, i.e. folder does not appear in path (/edit/... and /share/... etc).
q=string -> the filter widget, string matches strings in title, description, tags; whole and partial matches
Trailing slash is optional on `/accountname` and `/foldername`
## Patreon integration?
https://github.com/naturalcrit/homebrewery/issues/697#issuecomment-972366463
> I also just thought about this, but something that users that monetize their content might appreciate is a Patreon integration.
>
> Creators could authorize their HB account with Patreon, and when publishing brews could mark them as locked behind certain patron tiers they have.
>
> Patrons would also need to authorize with Patreon, but after doing so could visit the creator's page and see all the content available to them based on their subscription tier with that creator.
>
> I've worked with the Patreon API in the past and it's currently undergoing a pretty big shift, just noting this for the future if the idea seems nice.
Alternatively, users could maintain a folder for each tier (possibly even a smart-folder to auto-select based on tags), and set a password on each such folder. Patrons with the password can view and access the contents. The creator can change the password monthly to restrict access from unsubbed patrons, although that sounds like a fair bit of fiddly work (but doesn't require any special coding/development).
## Data structures
Thinking through data structures for folders and where we store that data .. each folder smart or dumb would likely need its own mongo data object and id. (It would have properties like folder-name, parent-folder-id, password, smart-rules, view-count, etc)
Since different users would have each their own user folders, and maintaining that, it doesn't seem sensible to simply have a list of folders stored as a property on each brew, not even as mongo-ids instead of folder-path strings. Alternatively, each folder object could have a list of brew-ids, which are the brews stored within. Again though, there are normal-form smells.
Understanding how these brew ⇔ folder relationships are to be queried could be useful. We definitely want to start with a folder and list out all the brews contained within. If we do go with the brew-in-many-folders idea, then reflecting "this brew is in these of your folders" could be informative. Searching by filter or tag on the userpage should reveal any matching brews, even if hidden inside a folder, so that also implies a need for determining enclosing folder starting from brew.
In normal form we would have brews, folders, memberships as separate tables, with brewID and folderID tuples stored in memberships (along with userID, of course). Now, I do understand that mongo is not a table-and-columns centric thing like SQL is. I'm not super up to speed just in what manner it is different, I just know its different, and thus to be cautious with structural assumptions. That said, is it very-un-mongo to have multiple tables, to have a joining table like how it would be done in SQL?
### Folder Object
- folder id (nanoid, required, auto)
- folder name (string, required)
- parent folder (nanoid, optional)
- password (string, optional, hashed)
- view-count (integer, auto)
- icon or image (string, optional) (#240)
- styling (css-text-block, optional) (#240, #1843)
- published/public/hidden (string, default public)
- brews (array of brew ids)
- folder type (smart/dumb) ??
- smart-rules (???)
-
### Brew.system?
Via #240, a reminder that `brew.systems` is already implemented .. but would be subsumed by the `system` category of tags (e.g. `system:5e`). Would need a PR that converts any old brew.system values loaded from a document into new brew.tags.
- tags
- description
- brewCount
- authors
### Problem: multiple authors
If we do go with the brew-in-many-folders idea, then reflecting "this brew is in these of your folders" could be informative. Searching by filter or tag on the userpage should reveal any matching brews, even if hidden inside a folder, so that also implies a need for determining enclosing folder starting from brew.
## Roadmap
TL;DR:
- mongo stubs for google brews
- dumb folders
- brew tags
- smart folders
## Roadmap (outdated, needs revision)
More detail:
- hidden status vs published/public (needs: none)
- dumb, flat folder - behind the scenes structures
- create/delete/rename folders on user page
- designate folder for brew in metadata pane (via picker UI) (prereq: dumb flat folders)
- designate folder for brew in metadata pane (via picker UI)
- create/delete/rename folders via picker UI (prereq: picker UI)
- designate folder for brew on userpage (via picker UI) (prereq: dumb flat folders)
- designate folder for brew on userpage (via drag&drop) (prereq: dumb flat folders)
- designate folder for brew on userpage (via picker UI)
- nested folders (prereq: dumb flat folders)
- nested folders
- update picker UI for nested folders (prereq: nested folders)
- brews in multiple folders (prereq: dumb flat folders, designate brew folder)
@@ -228,7 +136,14 @@ More detail:
- smart folders (???)
^* Tags will eventually be exposed via the Published Brews regime, and so we need to take care that users don't co-opt the system to attach what they think are private tags onto what might become public brews. **Thus, we need to roll out folders before tags**, otherwise users will be very tempted to use tags as an organisational architecture (i.e. folders).
Not all the folder stuff needs to be done before tags. Just dumb flat folders would suffice to start.
related issues and discussions
- https://github.com/naturalcrit/homebrewery/issues/697
- https://github.com/naturalcrit/homebrewery/issues/758
- https://github.com/naturalcrit/homebrewery/discussions/1471