-
Notifications
You must be signed in to change notification settings - Fork 44
Implement editable blacklist / forgetlist -- work in progress #84
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
2. icons less opacity onhover of results 3. cleaned up css file for visit items (proper naming for classes) 4. a bit more structured css file (although that is only superficial to be able to read the blocks better)
Good start. I wonder what the reasons were for choosing (and switching) between |
Hi guys. I'm looking to contribute to this feature/issue #20 to help out a bit. At the moment dev is being done on @aquibm's fork, and seems to be going well, but I don't have write access to add further commits to this PR. What do you suggest is the best way to go about this? I could send a separate PR to @aquibm's master branch, which after being merged in would show up in this PR (kinda weird, and I would need to continually make sure I'm in-sync, but it would work I suppose :S). Or we could have a discussion about having mutual write access on a fork and make the PR from that? |
@poltak Thanks for helping out! I've added you as a collaborator on my fork, you should be able to update this PR now 👍 @Treora The switch was mainly to make it easier to read the list of blacklisted sites without having to setup a persistant store / reducer on the other end. We could also switch out the storage area type to be |
- super simple; just setting up controlled input state so store is always up-to-date with user input there - removed that unused dupe import as well - add init input state (empty)
- remove all the 'inputName' related logic - need to pass additional input onChange handler fn down from container (will wrap the redux action to have a 1-1 state update to user keypress) - replace the onSaveClick logic (blacklistNewSite view) with just a call to onAdd (container now has access to input val, hence don't need to get inside view comp) - replace the handleAddClick logic (blacklist view) to just directly call onAddClicked (debounce can be done in container binding; focus can be done in actual <input> el's ref, or by autoFocus att)
- add btn debounce now done in method binding (lodash was already include in project, so might as well use that) - add onInputChange method, which just wraps around redux action to replace input state when user types - onNewBlacklistItemAdded method now don't need to be explictly fed-in the input's state; it is now in scope of the container via mapPropsToState (same if it was in component state instead of redux) - update mapPropsToState to just map everything in the state.settings bucket to container props (as this is the settings container)
- another common action with the input state - now explicitly called as part of the onNewBlacklistItemAdded handler method, but also could be triggered by addSiteToBlacklist action
- refactor commit - often that prop was being extracted from this.props and used as 'actions' which was already declared in top scope (from import) - no problem, due to scoping rules, but can easily lead to weird errors if someone forgets to pull 'actions' from 'this.props' first and unintentionally tries to use the top-level 'actions' var
- try to keep all user interaction logic in container and redux (when needed) - also moved from using event.which to event.key (not super important, just makes the code more readable for those not as familiar with keycodes IMO) - also means onCancelAdding doesn't need to be passed down - reset the input state on user cancel (pressing escape)
- refactoring commit - now they're passed all needed controller logic and just dumb views, so might as well remove the explicit returns and braces
What do you guys think about getting rid of that ADD button (top right) and just having the input row always shown? Just a suggestion (you could have other plans with it already). I think it simplifies the possible states of this view, which is always nicer for the user, and we could make some style to visually re-enforce that its purpose is as input and not a data row (I'm terrible at coming up with visually-appealing styles; take the screenshot with a grain of salt). |
I see your point. I think we will anyway add redux state to the background process soon, which makes it a smaller step to take, but maybe we will be happy with this solution too. As said, I am happy to start with something and improve as we go. The important thing is to keep things modular enough to easily improve them later.
Remember that we do not only target Chrome (it seems Firefox support for @poltak: thanks for popping in and helping out! I like the design example with the input visually mixed in as one of the entries. I actually wonder if the column with date added gives relevant information. As a small heads-up: at some moment we may wish to configure more types of behaviour than just ignore/store (blacklist or not). For example, some sites I may wish to index the text content, while for others I want to also store the full page. Not sure if we will want all these 'site rules' in a single list, but it may be good to keep flexibility for extension in mind when coding this widget. |
Indeed, I could imagine it simplifying the entry process, as it could remove a few steps of entering new items.
What you, @poltak propose with removing the button, someone would just type in in the last row the regex and press enter? If that is the case, indeed removing the add button would remove step 1 and 2. I think we could leave it out for now, if the current purpose is just adding a new line.
I would agree to that. What use case did you have in mind for that @aquibm?
From my perspective, it think it is best to leave it simple for now with just a regex in a single list, so the basic feature works. I feels a bit like over engineering to optimise for more use cases than regex, as it covers already a good amount of them. (domain, url, expression) |
I feels a bit like over engineering to optimise for more use cases
than regex, as it covers already a good amount of them. (domain, url,
expression)
Not sure what you understood here. I meant that rules would still be
regexes.
I can see the point of adding other use cases later on. Seems like the
question "index or archive?" could be a separate list.
Could also be separate. Right now I tend to think they would make more
sense together, as these are different answers to the same question
(index, archive, or neither?). This was just one example though, more
behaviour aspects may appear that people may wish to configure. Let's
solve the problem when it is there though.
|
I meant basically any other form of improvement except pure regex. As for example your index/archive/ignore option or things like whole domain (which then could be possible if you have the whole url and say "whole domain". An option which could extract the domain name and blacklist it. i.e. used in a quick blacklist function. So yeah, lets solve it when its there. |
- leave empty toolbar div there for further feature btns that we may need - clean up container logic relating to input row's enabled state
- now have control of that input from the container - focus it after render and blur on escape key press
- can add more input buttons now and they will fill up that container - make the input row look obviously different to the other rows (can change this; mainly just the background and font now) - replace the relative positioning of btns with flex
- nothing special
@poltak and me just had a chat in slack about how we could do it. There was a question about if it makes sense to add simple logics (*, ?, ., etc) to the regex. For the sake of simplicity, I think it is enough to just incorporate the "all urls containing the following string" use case and not think about regex rules. With this case people can blacklist a domain “mybank.com”, a path “mybank.com/dashboard” and a whole URL "mybank.com/dashboard/print.html". To not have to create a new work-flow of validating the spelling of the entry, a simple white-space removal would do the trick. At least there is currently no other use case that comes to my mind, that would make the entry unsuitable for enforcement. Any other that come to your mind? |
- just use String.prototype.replace to delete any whitespaces in the input before storage
- after whitespace has been stripped from input, make sure something is still left in that string before dispatching the add item action
- thought might as well give them disabled state as it's super easy and gives nice visual indication for user based on those simple validations (prev 2 commits) - if it ever gets anymore complicated, this logic is better done in the parent container and pass down disabled bools as props
@oliversauter:
There was a question about if it makes sense to add simple logics (*,
?, ., etc) to the regex.
How do you mean to 'add them to the regex'? Using '*' as a wildcard
would conflict with regex semantics; better to drop regexes completely
then, which is fine too.
For the sake of simplicity, I think it is enough to just incorporate
the "all urls containing the following string" use case and not think
about regex rules. With this case people can blacklist a domain
“mybank.com”, a path “mybank.com/dashboard” and a whole URL
"mybank.com/dashboard/print.html".
Also I see currently no other use case that would make regex necessary.
We have been talking about using regex matching because it is expressive
and easy to implement, but it would be totally fine to do some other
type of matching. Some options:
- Just literal substring matching (probably too crude).
- Full string match, but interpreting a '*' as wildcard (easily
understood, bit still somewhat crude).
- Some URL-specific rule type, e.g. like [url matching
patterns](https://developer.mozilla.org/en-US/Add-ons/WebExtensions/Match_patterns)
in WebExtensions.
- Regex (not so user-friendly, but easy to implement)
Choose whatever seems easy enough to implement good (easy) enough to
use. If anyone wants to put time into it, a url-specific approach is
probably best (is there prior art available for reuse?). Or at least,
make it easy for users to just enter a domain name (e.g. mybank.com),
and have it match both http and https.
To not have to create a new work-flow of validating the spelling of
the entry, a simple white-space removal would do the trick. At least
there is currently no other use case that comes to my mind, that would
make the entry unsuitable for enforcement. Any other that come to your
mind?
You mean spell-checking the domain names? :)
If input validation is needed depends on which type of matching rules we
use. Not sure if white-space has to be removed or just url-encoded like
any special character.
|
agreed.
As mentioned, both of them would cover a good amount of use cases we need right now, even if crude. I agree that regex is not user friendly and also has no use case right now. If there aren't any objections, Iets go with the simple substring matching as it is currently working in the worldbrain extension.
In that case it was rather meant for spelling in the sense of "are there characters that can't be used to match a URL", as for example a white space. (Any other characters that you have in mind? Chinese symbols? :) ) |
URL validation seems to be a messy problem. Chinese characters are fine and even emoji are valid in URLs (all gets resolved to ASCII using punycode). Pasting Have a look at the "These URLs should fail" part of this matrix. My question is what should we do if the user puts in any of these (as an example)? I think the most simple way to handle naughty input, without introducing a validation/error state, is just let them add whatever nonsense URLs like this and then later, in the part of the extension that is going to do the actual URL check against the ignorelist values, just ignore these values. Depending how the check will work, it may not even matter as something like |
Another question: If I enter and save |
- adds roughly 385KB of assets to the extension
Preview of where it's at now: https://streamable.com/fcpbd Also just realised an inconsistency in that gif: saving via enter key press keeps focus on the input, while saving via the save button click loses focus. Should probably choose one for consistency-sake (I'm for keeping focus; prevents swearing at the computer when trying to enter multiple things). Just put the material iconfonts inside the webextension code and replaced the CDN link as well. UI-wise, what more needs to be done here? I can think of:
|
We can also add some instructionary sentence above the list. Will think about one.
+1 for refocus
+1 for making duplicates for now. I would file it as an improvement to make later.
+1 for removing, doesn't add much value.
+1 for skipping and also filing for future improvements. |
- previously would refocus after save via enter press (since it doesn't need to lose focus), but would lose focus after save via save btn (because it needs explicit refocus call on that element) - move the focus on the input ref to its own method since it's called multiple places; not needed but makes easier if focus becomes more complicated later
- doesn't really need to be table structure anymore but maybe want to add more columns later on
- mainly to remove the mention of "regular expression"
- VisitAsListItem component was the main part that diverged between upstream and this fork repo causing the most pain - kept changes to VisitAsListItem made in this fork in commits: - 1d5bd1a - d5aae46 # Conflicts: # Readme.md # src/overview/base.css # src/overview/components/ResultList.css # src/overview/components/ResultList.jsx # src/overview/components/VisitAsListItem.css # src/overview/components/VisitAsListItem.js
- refactoring commit - should be applied to all buttons in the blacklist - all buttons should now be <button> instead of <a> for semantics - takes care of overriding default button styles, hover and disabled states - change <span> in `blacklistNewSite` to be <i> - change <a> in `blacklistRow` to be <button>
Explicit merge in of all new changes from upstream
@poltak: A quick point already: designing for having multiple things that will be configurable, it would be neat to have the blacklist-related things grouped together (i.e. organise by feature). Also, it looks like you tried to merge with master branch, but ended up also including some outdated (and some worldbrain-specific) commits from the in worldbrain's master branch. In general, you may want to use rebase instead of merge to get branches up to date again. I just rebased it to master, see branch blacklist. Feel free to reset your working branch to that one, or alternatively to work on that one instead (just invited you to repo contributors). |
@Treora:
Yeah the intention here was to get the wordbrain repo up-to-date with most of the changes it was missing upstream (this repo) while keeping all the UI changes that were since made in the wordbrain repo. However, I never intended that merge to come back to this PR... Ended up doing that via an explicit merge as there were 3 main commits in the worldbrain repo that changed the overview UI, which ended up conflicting with a lot of changes from here that seemed to be related to fixing linting errors and refactoring. Dealing with resolving the conflicts in a single explicit merge commit seemed a lot less painful than rebasing the commits from worldbrain and resolving them one-by-one. But point taken, I'll try to stick to rebasing changes on top of branches to keep things up-to-date from now on. |
Check with Oliver, but as far as I know those UI changes are superseded as they were made for PR #82 (where he impractically made the PR from his master branch), which was replaced by (and partly incorporated in) PR #55. In any case, to prevent headaches later on, I would really recommend to always rebase instead of merge if you want to keep branches and forks in line with each other. It is not trivial (no pun intended) to work on your own fork while still incorporating changes from upstream – assuming that is your intention (you may of course decide it is easier to just run your indepedent&disconnected project, though we would lose the synergy and would have to do many things twice). |
@Treora I've refactored all blacklist code into its own feature module, based on the ideas in that link. Module entry point exposes:
No selectors in the code so far and haven't exposed the underlying view components, as I can't see a good reason to yet. All in refactoring commit 41bd0b9. See what you think of the general structure and we possibly can stick to something like this for all future feature modules, or at least UI code? Also refactors the blacklist state from being located at Furthermore, what do you want to do with this PR now that you made the
There is also some non-UI blacklist commits on WorldBrain implementing the actual blocking logic in |
Great. Looks much better now, with the blacklist folder. A few high level comments:
The blacklist branch is rebased on master, so better continue with that. Either as a new PR, or by doing a
Nice; can be added, or can also be done as a separate PR to review and discuss things one step at a time. |
This work was continued in #93, cleaning up this PR. |
Changes:
Todo:
Fixes #20