Steeditor is now as modular as I wanted it to be. Thanks to this, new features are pretty easy to implement. If you are interested what has already been added and how it was done, this post is a short summary of my work.
Utopian built-in templates have been in Steeditor since the beginning. However, previously you could not add your own templates and create drafts based on them.
This is not true anymore. Templates creation flow is finally here!
The UI is probably not the most beautiful right now, but it is easy to change.
Templates are stored in the IndexedDB (just like drafts), thus they are accessible offline.
The implementation is very similar to the draft's one, both when it comes to ngrx-related functionality and routed feature module.
Toolbar and images upload
I have added a very simple toolbar for the editor, with most commonly used elements:
- headings 1-5
- bold text
- italic text
- strikethrough text
Besides them, a "fullscreen" mode was added, which is useful especially on mobile devices. However, it's implementation is a bit tricky.
I refactored low-level components responsible for handling body form field - now there is a
BodyCardComponent (wrapper) which is a parent component for
BodyCardComponent is interesting - when a user turns fullscreen mode on, it dynamically creates itself inside a dialog.
All of these are cool, but the most important feature is definitely images upload. It uses Busy's file hosting inside a
FileUploadService. Now you can upload your thumbnail or image directly from Steeditor.
Actions on broadcast success
Pull request: Add bottom sheet on broadcast success
This is a very simple feature which lets the user open the post that was successfully broadcasted on busy.org, or delete a draft. Nothing fancy there.
More technical changes
These changes maybe aren't so exciting, but definitely were crucial for the features described above. From a developer point of view, they are much more important.
This section is gonna be quite technical, if you are not interested, feel free to skip this part.
- Implement Steemconnect module
- Integrate Steemconnect module with app
- (fix) Map broadcast response to
In my previous contribution, I announced that I want to create a Steemconnect NgModule which will eventually become a library. This is already partly done, NgModule is working fine, but there are a few things I want to change before it becomes an NPM package.
However, I'm really satisfied with the simplicity of the public API, for example,
SteemconnectOAuth2Service has only two public methods (
logout) and one getter (
To sign in user, one has to import
SteemconnectModule in the root NgModule, inject
SteemconnectOAuth2Service into service or component, and call
login method. Everything else happens under the hood, and the result of that is
authState Observable, which returns either null if user is not logged in, or object with
uid (username) and
token properties otherwise.
Once the user is logged in, to broadcast operations one has to inject
SteemconnectBroadcastService and call
broadcastOperations with operations as argument. That's all. As simple as that.
The access token is attached automatically on every request to Steemconnect by HTTP interceptor.
- Implement IndexedDB service
- (fix) Use
storeNamein every operation
- (fix) Change Store creation strategy
A reusable IndexedDB service was definitely necessary - now it's used both by drafts and templates. It is a very simple implementation, I keep using
idb library, but in the service all CRUD methods are Observable-based.
Nothing spectacular, but crucial for the application anyway.
Before this change, some slices of the state were managed on the root NgModule level (router, auth, login) and some on lazily-loaded feature module level (drafts). While it was working fine back then, when I started implementing templates I got into trouble - to access state managed by lazily-loaded module it has to be loaded first.
I decided to centralize the store to make it more predictable and to become a real single source of truth. This change also flattens the file structure for each feature store, and I just think the current implementation is cleaner and easier to maintain.
At the moment there are 4 feature stores: auth, drafts, templates, and router. Each is independent, but all are eagerly-loaded.
Two of them (drafts and templates) are using
ngrx/entity now. This library makes is super easy to manage entities collections.
- existing posts editing
- unit tests for ngrx-related stuff
- dashboard as a default route for logged in users
- UI improvements for /drafts and /templates routes
- README update