Fedi Developer (of crushes) :flag: :cute__i: (nprofile…y6jc) this but unironically
give qtquick/qml a try. you can probably make a working frontend pretty fast. it can do oauth2 for you (even refreshes the tokens) and if you’re just going for proof of concept quality you can do the rest entirely in qml/js instead of writing model/view classes and so on. it’s stupidly easy and i would have done it long ago if it didn’t take me until yesterday to realize just HOW easy.
roughly:
* build system: just use meson; the qt6 module it comes with takes perfect care of the details and it’s much better than the cmake/qmake stuff in official tutorials
* pass QML files to qt6.qml_module() and cpp headers (those that contain QObject classes) to qt6.compile_moc(), add the return values to the sources for your executable target
* have a class that does Qt’s OAuth2 stuff to authenticate and exposes the bearer token as property to qml (one line with the Q_PROPERTY macro)
* you can wrap API stuff there as well but you can also just use XMLHttpRequest and WebSocket in QML/js!
* to store settings/credentials, either have a simple class (Qt does XDG and INI for you), a complex class (libsecret?), or just store everything in sqlite from QML via LocalStorage
* have some ListViews in a GridLayout for posts, notifs and stuff
* you can shove json arrays of objects directly into the model property
* set the delegate property to an Item/Component that represents each object in the model (for example, an Item containing a GridLayout, Image for pfp, Labels and a Text to render markdown/html or w/e)
* in the delegate, you can directly reference the json object’s keys by name
* it’s a two-way binding by default too so if your thing changes a value, the change will propagate to the model’s data and emit update signals to wherever else it’s being displayed as well: you hit the fav button and the count goes up in all views that share the same model or are otherwise connected to that signal (e.g. notifs model could also update its count for the matching object without waiting for the api roundtrip)
you basically spend 99% of the time just writing markup and declarative UI behaviors/states/animations and tweaking the visuals/interaction flows for that kind of app
for performance you can:
* set asynchronous: true on anything that has it (e.g. Image)
* use Loader with that same property for view delegates
* cache the delegate item dimensions for each object in your model and (declaratively) tell the Loader to swap its source/sourceComponent with a simple rectangle of the same dimensions whenever it becomes invisible (e.g. scrolled out of view) - this saves memory and simplifies layout calculations for off-screen components (better than just unloading: nobody likes a jumping scrollbar)
later stages:
* you can pretty easily embed mpv as qml widget
* for the Loader trick above, you can just have those widgets render to textures (layer property) and:
* keep playing even while the Item scrolls out of view and is destroyed
* do a “pop-out” animation so it stays on screen if it’s currently playing while scrolling out of view
