-
Notifications
You must be signed in to change notification settings - Fork 327
Folders: Collected Clippings
This is a file of collected clippings of conversations from gitter, discord, reddit, github, etc.
It's a chaotic mess. Don't try cleaning it up. Do copy/steal interesting stuff into the main wiki topic page for folders.
Initially you'll be able to filter by tags on the user page, but as we get user settings set up I plan on adding smart folders to the list that key off of tags
Dumb folders are just smart folders with a specific structure of nested tags, unless you're planning on having them correspond to real disk folders instead of just simulating that with metadata.
/{route}/{route}/{resource} vs /{tag} and /{tag}
Hmm .. no .. folders will be a mechanism to view a curated collection
of brews. Each of those brews will have a resource uri of just
/user/name/:brewid
— the folder path will not be exposed (for a
couple of reasons).
Or maybe not. [RESOLVED: folders have visible paths, brews are direct by :id]
If we have "folders" which act as views of curated collections of
brews, and have urls like /user/name/foldername
or
/user/name/foldername/nestedfoldername
.. and requesting that url
reveals the folder contents .. the brews listed there wouldn't include
the folder path in their respect URIs, right?
They'd be things like /share/brewid
or /edit/brewid
. Right?
Given the brewids are becoming perma-identifiers, while folder names
could come and go and mutate, and possibly even a brew could be placed
into multiple folders of one user, and certainly a multi-author brew
could be placed into multiple author folders (since folders are owned
and managed as a user thing, not a brew thing) .. it would be making a
lot of hard work for us to try supporting /share/foldername/nestedfoldername/brewid
(especially since the route could be parsed by totally discarding the
folder-path middle).
Dumb folders could be inferred from an array of strings in a code fence in each brew - unless we want to make it easy for users to rename/move folders (likely), and use a picker UI instead of “type the path string” UI (also likely). Would also support creating empty folders.
[RESOLVED: separate mongo entity, folder object contains array of brewids ]
What smart folders are is a folder that instead of having a static set of items that only changes when items are added/removed is a query that calls for documents that meet criteria.
On smart folders, would we want criteria other than just tags? Probably not for v0.1 of course, but eventually .. things like smart folders for "edited recently", "viewed recently", or "most popular brews"?
FWIW the idea of smart folders based off tags was going to be implemented after we got user settings set up -- that way you'd only see folders you created
We still need dumb folders before/contemporaneous with tags, to avoid tag-misused-as-folder behaviour. (Assuming tags will become public facing in various ways).
I think that overall smart folders would likely not be able to do more than a query URL but it would give a nice UI. The only advantage it might have is being able to nest it. So a dumb folder that holds smart folders, etc. Its just a UI to hold queries in the end though.
I think the easiest way to make them useful would be to allow them to hold folders in addition to a query. So you could put static items in a smart folder so long as they were inside a dumb folder.
My personal desire for smart folders is the ability to group homebrews simply. Having a folder for "forest" and a folder for "monsters" and making a dryad statblock and it automatically goes into each when given those tags. Or for instance making homebrew and tagging it with everything relevant but also "campaign X" and having it go to the campaign folder that the players have access to, even though it was created in a different folder originally.
Smart folders could simply be dumb-folders with non-blank smart-criteria. That way not only can the smart folder be placed inside another folder (dumb or smart), but could also have other items (brews, folders) placed within it.
(tag1 AND tag2) OR (tag3 AND tag1 AND tag4) NOT (tag5 OR tag6)
We could likely get away with a simple structure of an array of queries, each query being executed in order and compiled into one collection. The simplest version would be
[
[tag1, tag2, tag3],
[tag6, tag7]
]
.. but lets look ahead a little bit and make that more explicit, like this..
[
{ "and": [tag1, tag2, tag3] },
{ "and": [tag6, tag7] }
]
.. so we could later extend that to this..
[
{ "and": [tag1, tag2, tag3], "not": [tag4, tag5]}, // or ..
{ "and": [tag6, tag7] }, // or ..
{ "and": [tag8]}, //
{ "omit": [tag9, tag10] }, //
{ "omit": [tag11] }
]
But that is getting way ahead of what would be needed. Probably ever.
And also doesn't even support non-tag criteria. /sigh.
Folders will have a parent-folder-id
property. That way a simple
nesting hierarchy can be established, and we don't have to worry about
loops. A blank parent-folder-id
just means it is in the root (i.e.
userpage).
[later...]
There is some use cases where being able to place a given folder into multiple other folders (e.g. "Social Policies" into "Friday Game", "Open Table Group", "Thursday Group").
Since all brews and all folders are retrieved as flat data tables and then assembled for the userpage, this approach won't actually violate the Laws of Time and Relative Dimensions in Space and we can cope.
More thought and discussion is called for.
Ah and at that point we'd need Folders to exist as a whole separate Mongo object that has relations back to brews, so we can use object ids as urls instead of folder names
Object ids instead of folder names as user-facing UI ? hrmm
Would be useful internally to avoid breaking links when things get renamed
But I do like being able to rattle off “/users/erics/friday-game” in a socmed chat to a new player.
That's also fair -- and for that we could get into published folders vs unpublished ones if we wanted
URLs being object ids would also allow you to share them more privately so people don't just url spam until they find a valid folder
object ids would also allow you to share them more privately so people don't just url spam until they find a valid folder
This is a difficult problem. We want users to share a folder, but only to a limited audience, most/many of which won’t present any credentials on request. An obfuscated mumble-token does work for that, but does require sharing that mumble-token instead of the friendly name.
Another method might be basic auth on the folder .. share the friendly url and the password and your anon buddies can view. Others guessing the friendly url hit the gate, do not pass go.
Maybe do something like Google sharing URLs!? Generate a "token" that is passed as a query parameter and lasts until it is revoked -- if the token isn't present and valid then you can't access the folder
Hmm .. sociologically I like the having the "token" be named a "password". Not only has it the tech features, it also communicates “this is a private space”.
Was almost about to suggest three states: folders anyone can view with the url, password required, and folders only I can view. Yeah nah, this can be done with just a password field: no password, password shared, password not shared. Problem solved.
Side note: an author should not be prompted for the password of a password protected folder if it is a folder they created.
Minor issue of leakage of existence tho (password prompt vs 404). People will know you have a folder named "My Naughty Brews", there would be no plausible deniability. We could always force the password to be on a query param instead of in the browser window.
So /../folder
→ 404, but /../folder?p=secret
→ access?
And /../folder?p=wrong_secret
would also be 404
I assume only the OG author can add and remove authors?
I assume only the OG author can add and remove tags?
So that's the thing -- we don't actually have a way to distinguish the original author vs added authors. So while this is obviously a huge improvement, it could still be a problem if someone malicious was given edit access
Secondarily, only letting author[0]
edit authors would be nice but
at least preventing removal of author[0]
would be ideal.
Hmm. Well I would like to at least see author[0]
never being able to
be removed if nothing else. It would be dumb if someone could remove
your perms after you shared it…
Eventually, this might be managed via a owningAuthor
field on the brew.
The existence of an originalAuthor
field, more properly known as
owningAuthor
field, would imply the existence of a transfer ownership
UI.
And raises questions about what happens with google-drive brews when the owner changes.
Hmm .. we’re gonna have to hold off on brew tags until we also get user folders implemented .. because users *will() use tags as folder-proxies, and I don’t want to see a folder magically appear named “dumb shit I’ll get to later” (because of an added author adding a tag). Especially if I have that brew marked as Published.
FWIW the idea of smart folders based off tags was going to be implemented after we got user settings set up -- that way you'd only see folders you created.
[RESOLVED: we've since this discussion moved ahead and implemented tags]
I think the best plan for tags to start is just an incremental release where we release the ability to add tags, they show up, and you can filter by them
Those are just two separate tagging mechanisms. You could have a url route strategy which displays them differently, but I'm not sure why they'd have to be implemented as entirely different systems. It seems redundant. What I'm saying is that you can implement folders using whatever framework you come up with for tagging files. They don't have to internally be two systems.
Now, in theory, both types of folders (dumb, smart) could be done with tags. A dumb folder would be "show all documents with the tag (read: folder ID) 'folder:j12h3j2ebjy'", and a smart folder would be "show all documents that are tagged as a monster and made by jeddai". Adding a document to a dumb folder would add the folder tag. Showing the tags that dumb folders use would be a suboptimal user experience because I imagine that a folder ID would be a UUID or something similar, but that is a way that could do both.
On the other hand, it would be more convenient to store a list of brewids into a folder object, instead of folderid (or list of folderids) into a brew object. A) If a folder is deleted, it would entail deleting one folder object (vs updating multiple brew objects to suit), and B) things get messy when different users can and will put the one brew into each of their own folders (folders are user centric objects).
All public tags are actually "public:{tag}" and the tag search only looks for ones that match 'public:{tag}'. Or maybe the reverse of that, it ignores tags that have 'private:{tag}'
However, “private:{tag}” clashes with an idea of tag categories. Like “system:PF2” and “genre:Fantasy”. Look at GMB high-level categories of tags for practical examples.
That said, perhaps an attribute could be added to tags, like "genre:erotic-punk{private}".
This is all orthogonal to whether a brew is published or not. This is about whether a published brew would have all the author tags made visible on that brew.
[RESOLVED: nope]
Bogging down the server with complex and large queries is not exactly optimal so I imagined you guys would find some reasonable limit that gave it minor flexibility without punishing your usage
The full list of a user's brews would be retrieved in one call on the back end, and then they are processed and displayed on the front end via react. So, at worst, it only slows down the client not the server. All the same, I'd prefer simpler too.
Hmm .. if a brew is put into a dumb folder, we'd remove it from the top level view. But what happens to brews that appear in smart folders [according to smart criteria]?
Smart folders would likely be "illegal locations" to store a brew, they merely query them from other locations. So it would just be wherever it was created, root or dumb folder, but also the smart folder.
Wait .. if someone was thinking they'd use smart folders to tidy up their userpage, then they'd be disappointed. They'd have to manually shunt all the brews they want not visible on the base userpage into a dumb folder.
Would smart folders scan all brews, including brews that have been shunted into either sub-folders or even into sibling folders? For example, I create a dumb folder for "My Traveller™ game", and toss all those brews in there. If I then have a smart folder inside that folder for tag=monster, I probably wouldn't want monsters from "My Pokemon™ game" to appear there, right?
Maybe that could be a filter? Or even just a checkmark? Like, "search sub folders" and "search sibling folders" would be options? because I can definitely imagine having a single monster in multiple folders. I can't imagine why a smart folder would be a valid location for a brew to live permanently though, because part of the reason to have a smart folder would be to keep the same brew in multiple locations without having to duplicate it. And it makes no sense to have a folder with no static values to be where a brew "lives" if it can also be seen in other locations?
Agree, smart folders are lenses, not locations.
Rename "folders" as being lenses? Does a nested hierarchy of lenses make sense? (Isn't that a microscope?)
I know that from a database perspective what I am talking about is more like a view. But I think for the average person that "smart folder" will more clearly express what it is than lense or view. I guess "filter" is fairly ubiquitous if we are looking for a new name.
We're using "filter" to refer to the free-form filtering widget at the top of the userpage. Hmm, no wait, we're also using "search" for that. I think "filter" as a term is only used in the backend or in a css class. Time for a tiny refactor to tidy up nomenclature.
People filter their emails and excel sheets.
True, "search" as a UI is usually thought of as a command-and-response, while "filter" is more a live and dynamic update of the view.
We're planning on allowing a specific brew to be placed into multiple dumb folders. Think of them as symlinks.
So just a desktop shortcut but for brews? xD
It would be cool to be able to share a whole Folder at a time, rather than individual brews, too.
It made me think it might be possible to use a Route like /user/:id/:folder_name to access another user's brews that are both Published and tagged with 'folder:{folder_name}'. Of course, that needs both tagging brews and brew filtering by tags to be in place and functional first, which at this point is are likely extensions to follow on from the current brew sorting work.
So the end user would only need to navigate to homebrewery.naturalcrit.com/user/Gazook89/my_homebrew_campaign to see all of that published material.
If we have "folders" which act as views of curated collections of
brews, and have urls like /user/name/foldername
or
/user/name/foldername/nestedfoldername
.. and requesting that url
reveals the folder contents .. the brews listed there wouldn't include
the folder path in their respect URIs, right?
They'd be things like /share/brewid
or /edit/brewid
. Right?
Given the brewids are becoming perma-identifiers, while folder names could come and go and mutate, and possibly even a brew could be placed into multiple folders of one user, and certainly a multi-author brew could be placed into multiple author folders (since folders are owned and managed as a user thing, not a brew thing) .. it would be making a lot of hard work for us to try supporting /share/foldername/nestedfoldername/brewid (especially since the route could be parsed by totally discarding the folder-path middle).
Yah. Punt the question of what do we do if
/user/name/foldername/oops-this-was-renamed/brewid
is clicked. Will
that be 404 NOT FOUND
, or 300 MULTIPLE CHOICES
(because it could
be in multiple folders) or 301 MOVED PERMANENTLY
or 302 FOUND
or
418 I'M A TEAPOT
?
It should likely be 400 BAD REQUEST
(because we simply don't support
routes-to-brews).
Also, is this a URI to a brew, or to a strangely named folder:
/user/name/folder/nested/Z2yOC6xNMpKc
. (The latter, of course, and
we shouldn't be asking the server to guess).
On the folder subject, my thinking was less folder hierarchy and more groups. Actually "group" might be a better term, as it doesn't imply a multi-layer parent-child hierarchy in the way that "folder" does. So the hypothetical functionality is that user's Brews can be filtered to a group of brews defined by the tag "group:group_name", perhaps accessible via a Route (e.g. /user/:id/:group_name). This should be a fairly natural extension to filtering Brews by title.
So my progression plan for this project is roughly [x] Sorting => [ ] Filtering by Title => [ ] Filtering by System => [ ] Filtering by Tag => [ ] Custom User tags
You know, in between and around the other stuff I'm already doing and need to get back to first.
On filtering: there are two different features to be considered
a shareable permalink that shows only the matching brews a UI widget that facilitates live filtering of the account page I have a javascript-injection stub that works for #2, although it can also be done via react.
On (1), a wrinkle might be not allowing escalation exposure. That is, if I give you /user/erics/fridaygame, you certainly could escape to /user/erics (of course), but I might wantsundaygame and fridaygame to not be visible from there (while still exposing lore).
I think groups could have a similar "published" status that hides them if you are not logged in.
In my thinking, group is a special tag. One brew can have multiple group tags, but the filter term 'group:A' will only find brews tagged with 'group:A'. Custom user tags can use [A-Za-z0-9], all symbols reserved for future use, so a tag containing a colon (e.g. 'group:erics') can only be applied through the UI. The structure itself is still flat, so in this thought experiment, ALL brews are still visible at /user/erics (to the user, and if published, the public) but are automatically filtered to just the group:fridaygame at /user/erics/fridaygame.
It's not impossible to imagine a publish_in_group:true tag that makes it visible to the public (like PUBLISHED) but only when viewed via the group.
A better version being publish_in_group:fridaygame, to specify which group to publish it in, rather than just publishing it in all groups it's attached to.
If I put a brew in a group, I would want it to be visible when that group is shared. I can't think of a situation for putting a brew in a group but the brew wouldn't be published. (Unless it's an unpublished brew?)
So it comes down to whether the tag/group/ui (e.g. fridaygame) is exposed on the home page. Someone could be given /user/erics/fridaygame, escalate to /user/erics, see some interesting tags there of published brews, and thus also visit /user/erics/lore to see a list of brews with that tag (because I've not hidden that tag).
The published/unpublished status of a brew should still be respected though. I might have a "Halloween Rules" brew I put into :fridaygame and :sundaygame and :mondaygame ahead of time, and only push to publish mid October. Similarly, if I un-publish "House Rules" then I'd want that to not be listed in any group, even if still tagged.
Yes, unpublished brews will never be visible to users who are not listed as an author.
Not visible in a listing. They can still be shared and visited.
On syntax of tags .. I think I wrote something on that at some point, something like :, where could be preloaded with {meta, type, system, version} and associated tags (e.g. system:D&D, version:2e, type:lore; or system:Pathfinder, type:adventure; etc). Hmm .. maybe not separate system and version. We'd still want to allow multiple tags of the same grouping, such as [meta:lore, meta:feats, meta:monster] or even [system:d&d5e, system:pathfinder2e]. There would be some nonsense or unlikely combinations, but we shouldn't preclude those possibilities
People are bound to have Brews that encompass Lore, Feats, Classes, etc. It's not hard to envisage a brew for a Homebrew race of unpleasant-goose-humanoids, for example, that has custom Racial Feats (Fly, Honk) and adds homebrew twists to existing Classes (Barbarian of the Golden Bell, White Feather Rogue) or creates new ones entirely.
Also possible someone might author a brew tagged [system:d&d2e, meta:feats] or even [system:d&d5e, meta:nwp].
And of course just because we pre-define meta, system (or game), and type, that doesn't mean a user couldn't mint their own grouping terms and tags (e.g. tone:silly).
Ugh .. does this mean we might also want to filter by grouping? "Show me all brews tagged with tone:".
Also, on the system vs version question
.. sub-tags that qualify the group:tag?
e.g. system:d&d:2e``,
tone:silly:very``.
(the Library Sciences part of my backstory is emerging)
Getting ahead of ourselves here though. We should perhaps reserve :
as a special character in tag names.
It certainly should be possible for a user to enter an ungrouped tag:
fridaygame``,
session_zero``, storytime
.
My thinking is that only tags that follow the form group:name
qualify
as groupings and would be accessible via ``/user/:id/:group` However it
should still be possible to filter by custom tags like tone-silly
[NB. the idea of implementing folders via tags i.e. group:
was later
abandoned. There are useful and helpful things we can do if folders
are maintained as separate objects.]
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).
Patreon integration should wait for folders.