-
-
Notifications
You must be signed in to change notification settings - Fork 842
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
Extract Composer state #2161
Extract Composer state #2161
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ok, I have a few things to say. Some general comments here, and also a few specific ones to some code.
I think we should have a ComposerState key
or something (like my rewrite Alert state) and use that as an attribute or class instead of a generic js-TextEditor
because
- What's the point of adding
js-TextEditor
toTextEditor
? They both point to the same elements and could target multiple ones - The key will be specific to one and stored in the state, can be generated randomly
- based on Date.now() is probs easiest way
- could use some UUID package or something
- or simply keep track of how many times the state has been constructed and add to the number
We may want a $()
method in the ComposerState to return the jQuery (or whatever alternative library) of the corresponding composer DOM.
I wouldn't be opposed to this, but iirc, the concern was adding unnecessary bloat.
The goal is to make it clear that js-TextEditor concerns javascript/functionality, not style. So someone could feasibly make changes to / remove / use elsewhere the TextEditor class, but not so much for TextEditor. I would probably prefer a |
Should we wrap bodyClass and props within a JS object like we're doing with alerts and modals? |
Can you elaborate? Not sure what you mean here. |
Well, we wrapped modalClass and modalAttrs into a ModalState class? Perhaps we should do something similar here for consistency so that composers are shown by passing in a ComposerBodyState? (but with different naming) |
That Unfortunately, I have no particularly good alternative in mind right now. The problem with JavaScript UIs is that there are so many different types of states. VDOM state (components and props), animation state, actual DOM state, cursor/focus state etc. And for some of these, it doesn't seem necessary to keep VDOM and DOM state in sync at all times, e.g. when the user is typing lots of words in the composer. Not sure where I'm going with this... |
The best alternative idea I have for the js-TextEditor is providing a unique ID. That would make ownership clearer? |
Can we not just use the |
I think this might be a react/vue thing, doesn't seem to do anything. We could, however, pass the texteditor dom element to the state in the config method? |
@askvortsov1 It's used for EDIT: Nevermind, it's not used there. I swear I've used it in the past though... We can still set it using the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I haven't read in full detail, as it's a massive diff.
Globally I think I'm ok with the approach.
Regarding the .js-
class stuff, I think that way of doing it is ok. I would even advocate we use an id
to make it clear we expect only one of those elements to exist at any given time.
Below a few other things I noticed.
52802c6
to
45eac47
Compare
5ae0366
to
e5e2d4f
Compare
f11821a
to
9155037
Compare
9155037
to
9b75ab9
Compare
Since it's a global handler, we should really turn it off when the composer is unloaded. In addition, listening to the event is recommended over setting the global property on `window`.
Brought up by Clark, and simply not working the way it was.
- The main breakthrough was moving the logic from Composer to ComposerBody. The former had to consult the state for logic and values readily available inside the ComposerBody (and its subclasses). - The state is no longer involved in the browser-level unload event handling. - It still has to take care of the manual confirmation message that is shown when the composer itself is closed while drafting a message. - The former does not need a custom message (it would ignore it anyway), the latter does. - The callback and the text that should be displayed are now passed to the state with a nicely encapsulating method. - While I was at it, I extracted a simple helper component for handling the event (de)registration. JSX composition is so nice!
2a96de6
to
050081c
Compare
This restores previous behavior. While all ComposerBody subclasses I know of provide their own default values for the `confirmExit` prop, this is technically not a given for other subclasses (e.g. in extensions).
This is no longer a component like it used to, but it is nicely separated from the rest of the state stuff, which only needs to hold (and reset) a reference. The class encapsulates the complex DOM logic for manipulating the contents of a <textarea> HTML tag. The methods are not just moved, but also simplified a bit, as no more conditionals about the existence of the textarea element are needed any longer. We'll see how that goes.
Based on what mentions and emoji were re-implementing themselves.
This makes it easier to determine the current responsive screen mode in JavaScript, without hardcoding (and therefore duplicating) breakpoints or CSS properties. Thanks to @w-4 for the great idea!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is now in a state where I can live with the remaining hacks and rough edges - I've noted down some of them and might try to tackle them at another time. But it's time to unblock the next step, which is upgrading to Mithril 2, and that (not storing component instances) has been achieved for a while.
Sorry for blocking that for so long.
These have been taken care of.
d7d7db5
to
7667761
Compare
* Fix closing the composer with ESC key Regression from #2161. * Remove obsolete method Regression from #2162. * Mark method as protected * Fade in posts in post stream using CSS This also avoids a double-fade from the JavaScript code, which was probably introduced in #2160. * Fix fadeIn for post stream items Co-authored-by: Alexander Skvortsov <sasha.skvortsov109@gmail.com>
This is needed to have access to the newly created SuperTextarea instance (app.composer.editor) directly after calling show(). Discovered when making ext-mentions work with the Composer state changes. As far as I could reconstruct, a synchronous redraw was also triggered in this situation before the changes in #2161.
* Fix closing the composer with ESC key Regression from #2161. * Remove obsolete method Regression from #2162. * Mark method as protected * Fade in posts in post stream using CSS This also avoids a double-fade from the JavaScript code, which was probably introduced in #2160. * Fix fadeIn for post stream items Co-authored-by: Alexander Skvortsov <sasha.skvortsov109@gmail.com>
This is needed to have access to the newly created SuperTextarea instance (app.composer.editor) directly after calling show(). Discovered when making ext-mentions work with the Composer state changes. As far as I could reconstruct, a synchronous redraw was also triggered in this situation before the changes in #2161.
See #1821, #2144
Changes proposed in this pull request:
Reviewers should focus on:
Confirmed
composer test
).