Everything is formatted with `dart format` (no flags) and linted with `dart analyze` ([see rules](analysis_options.yaml)). Both are enforced by the CI.
Lemmy devs are kindly hosting lemmur translation strings on their [Weblate instance](https://weblate.yerbamate.ml/projects/lemmur/lemmur/). Feel free to contribute strings there, we regularly sync string changes with Weblate.
We use flutter's native file format for translations: ARB, which itself uses the ICU message syntax. In most cases you will be able to deduce the syntax based on the source string. Here are 3 important examples:
1. Placeholders
`Hello there {name}!` - placeholders are put in a pair of braces, it will be later replaced with an appropriate value.
2. Plurals
`You have {amount} new {amount, plural, =0{messages} =1{message} =2{messages} few{messages} many{messages} other{message}}` - plurals are checked against their quantifier and provide 6 possible forms to choose from. In english this example does not make much sense, since we could just provide the `=1{message}` and `other{messages}` case. `other` case always has to be specified, it acts as a fallback.
3. Selects
`I will take a {distance_name, select, close{bus} far{train} veryFar{plane}}.` - selects allow for arbitrary matching against some predefined cases. All cases should be the same as in the source string.
Strings such as "_About one hour ago_" or "_~1h_" are localizable. We inherit a set of ready translations from [github.com/andresaraujo/timeago.dart/messages](https://github.com/andresaraujo/timeago.dart/tree/master/timeago/lib/src/messages) and provide our own in [lib/l10n/timeago](./lib/l10n/timeago).
To contribute time ago strings please send a PR containing a class that implements `timeago.LookupMessages`. Place it under [lib/l10n/timeago](./lib/l10n/timeago) with an appropriate name (locale tag) and finally register it in [main_common.dart](./lib/main_common.dart) in the `_setupTimeago` function. Each locale can have a normal (for example "_About one hour ago_") and a short (for example "_~1h_") variant, there are registered separately.
Lemmur is written in Dart using [Flutter](https://flutter.dev/docs). To communicate with Lemmy instances [lemmy_api_client](https://github.com/LemmurOrg/lemmy_api_client) is used.
[`MobX`](https://github.com/mobxjs/mobx.dart) + [Provider](https://github.com/rrousselGit/provider) is used for global state management, [flutter_hooks](https://github.com/rrousselGit/flutter_hooks) is used for local (widget-level) state management. `StatefulWidget`s are avoided all together and any state logic reuse is moved to a [custom hook](./lib/hooks).
LAC (Lemmy API Client) is used to communicate with Lemmy backends, more information can be found [here](https://github.com/LemmurOrg/lemmy_api_client).