Big-Fig / Fediverse.app

A client for Pleroma and Mastodon instances written using Flutter
https://fediapp.com
GNU Affero General Public License v3.0
141 stars 19 forks source link
android fedi fediverse fediverse-client flutter ios mastodon mastodon-client pleroma pleroma-client social

Fedi for Pleroma and Mastodon

Translate - with Weblate Unit tests Lints dartfmt

codecov

Fedi is open-source client for Pleroma and Mastodon social networks written using Flutter.

Pleroma and Mastodon are parts of Fediverse (decentralized social network). The main idea of Fediverse - nobody owns Fediverse. Anybody can run their server instance and use it to communicate with other people.

So Fedi is an open-source mobile client for social networks and has features similar to Twitter.

Follow us on Fediverse fediapp@fedi.app

Fedi

Android

iOS

Releases

Articles about how Fedi works inside

Table of Contents

Features

Coming soon

Feel free to open issues if you have suggestions

Known issues

Data gathering

Fedi doesn't use any special analytics service to track users. However Fedi uses Firebase services for PushNotifications(optional) and CrashReporting(optional).

You can completely remove Firebase via manual building from source.

Crash reports via Firebase Crashlytics

Fedi gathers crashes and non-fatal errors to make app more stable.

Push notifications

Push notifications are implemented via toot-relay-fcm server

PushRelayFCM is Ruby on Rails server which handles web pushes and relays them to FCM.

From 2.5.0 version Fedi uses PushRelayFCM mode without decryption on server-side. So all private data is safe.

PushRelayFCM and Fedi can work in two modes:

Without server-side decryption way

(Used in AppStore/GooglePlay versions from 2.5.0)

  1. Fedi subscribes to /api/v1/push/subscription with subscription[endpoint] set to relay server URL
  2. Instances send web push notifications to relay server
  3. PushRelayFCM doesn't decrypt message
  4. PushRelayFCM proxies notifications to Fedi app via FCM
  5. Fedi doesn't decrypt message and use FCM message with encrypted data as simple trigger to load latest notification via REST API (this will be improved in future releases)
  6. Fedi displays notification

Since PushRelayServer doesn't know private decryption keys, it can't access any private data.

Pros
Cons
Why Fedi doesn't decrypt message on client-side?

Because it is hard to implement with Flutter. There are no 3rd party Flutter libraries to decrypt ECDH p256v1 by now. It is possible to decrypt it in Kotlin/Swift and it will be done in the future.

With server-side decryption way

(It is not used in AppStore/GooglePlay versions from 2.5.0)

  1. Fedi subscribes to /api/v1/push/subscription with subscription[endpoint] set to relay server URL
  2. Instances send Web push notifications to relay server
  3. PushRelayFCM decrypts notifications
  4. PushRelayFCM relays notifications to Fedi app via FCM
  5. Fedi displays notification
Pros
Cons

Localization

Translation status

App uses flutter_localization API bundle with Flutter SDK.

It uses .arb files located in lib/l10n and generates .dart classes in /lib/generated/ folder.

After you make changes in .arb files you should do additional actions to regenerate Dart classes

Progress

Translation status

Help translate Fedi

License

Feedback

For developers

Flutter version & FVM

To build Fedi you need to specify Flutter version in .fvm/fvm_config.json field flutterSdkVersion.

You can achieve this by specifing your system Flutter version by using flutter version $version or using FVM

Flutter Version Management(FVM)

Fedi uses Flutter Version Management to specify Flutter version to build app.

FVM also helps manage several SDK's versions on local machine

Config is already done, so you just run fvm install in repo folder and configure IDE to use .fvm/flutter_sdk folder instead of system Flutter SDK.

To use flutter version specified in .fvm/fvm_config.json you should prepend fvm like fvm flutter install

More info you can found in FVM documentation

Melos

There a lot of useful comand line actions automated by melos commands.

Run fvm flutter pub global run melos run to see all possible melos actions

Libraries

You can find full list in pubspec.yaml where each library has comment why it's used

Icons

Tests

How to build from source

Clone repository

git clone https://github.com/Big-Fig/Fediverse.app

Go to repository folder

cd Fediverse.app

Install FVM

Install Flutter version used by this project

fvm install

Bootstrap with melos

Link multi-module project dependencies

fvm flutter pub global activate melos fvm flutter pub global run melos bootstrap

Copy default .env config

Copy config for prod and dev flavors

cp env_example.env env_prod.env
cp env_example.env env_dev.env

In Example config you can find out how to disable some features like Push notifications.

To enable all features you should change app id, create Firebase project, and edit config file.

Run
Run from command line
fvm flutter pub get
fvm flutter run --flavor dev

or

fvm flutter run --flavor prod
Run from IDE

Config Flutter SDK

Config Dart SDK

Run->Edit configurations

Run configurations

Flavors

There are two main flavors.

Implementation details: Build flavors in Flutter (Android and iOS) with different Firebase projects per flavor

prod

Is used for production builds

dev

Is used for development builds. You can use only prod flavor if you don't need special config for development

Config

Main purpose of config files is to exclude sensitive data from source control and quickly enable/disable and config some features like Push Notifications

Build script uses config from project root folder depends on flavor, so to build app you should have next files in root folder

env_prod.env
env_dev.env

Those files are excluded from source control.

You can find all possible config variables(with comments) at env_example.env

If you have strange errors or how to clean project

fvm flutter pub global run melos run clean

Sometimes it is also needed to clear iOS pods

fvm flutter pub global run melos run clean:ios

cd ios
rm -rf Pods
rm Podfile.lock
pod install

Sometimes you change package version in pubspec.yaml run pub get but version is not changed

rm pubspec.lock
rm .flutter-plugins
rm .flutter-plugins-dependencies
rm .packages
rm -rf .dart_tool
pub get

Sometimes when you change package version in pubspec.yaml and after pub get version is not changed. You can check pubspec.lock to see if version is changed. That may happen when you specify version bounds like >=1.0.0 <2.0.0 or ^1.0.0 which are the same. See Version constraints in official docs.

rm pubspec.lock
rm .flutter-plugins
rm .flutter-plugins-dependencies
rm .packages
rm -rf .dart_tool
pub get

Fedi specifies explicitly version like 1.0.0 to avoid such issues. However, that may cause dependencies version conflict

App ID

Changing App ID is required if you want to setup own PushRelayFCM server and pushes via your Firebase project for FCM.

It is also useful if you want to have several app versions installed on one device

Unfortunately, it is not possible to use APP_ID from config in all places in Gradle and XCode project files. So in some places ID is hardcoded

So, If you want to change app id from com.fediverse.app for prod and from com.fediverse.app2 for dev you should manually change them (in addition to changing id in .env files)

Actually, you should run Find and Replace com.fediverse.app with your package name on ios and android folders. And rename folders at android/app/src/main/kotlin

However, it may cause strange build errors. So you may need full clean

If you still have errors please explore App ID things in the next docs:

iOS group ids

Fedi uses group fediverse.app for prod and com.fediverse.app2 for dev

Signing

Android

Signing config is required to make release builds

Generate key via Tutorial and put it in android/key/key.jks(exclude from source control)

Create android/key.properties(exclude from source control) file with next template.

storePassword=pass1
keyPassword=pass2
keyAlias=keyName
storeFile=../key/key.jks
iOS

Follow official tutorial

Firebase

To use Firebase service you should generate files from your Firebase project page and put them in the project.

Don't forget to enable it in .env file

FIREBASE_ENABLED=false

Android

Put google-services.json to folder depends on used flavor

iOS

Put GoogleService-Info.plist to folder depends on used flavor

For more details see

Push notifications

To enable Push notifications you should

App ID and FCM server key(so and PushRelayFCM instance) are connected. It is not possible to use one PushRelayFCM instance with several App IDs and vice versa

On/Off via .env. Firebase Core integration is required

PUSH_FCM_ENABLED=false
Proxy PushRelayFCM

Is required if PUSH_FCM_ENABLED=true

PUSH_SUBSCRIPTION_KEYS_P256DH

User agent public key. Base64 encoded string of public key of ECDH key using prime256v1 curve.

PUSH_SUBSCRIPTION_KEYS_AUTH

Auth secret. Base64 encoded string of 16 bytes of random data.

More info in Mastodon docs and PushRelayFCM server docs

PUSH_FCM_RELAY_URL=https://pushrelay.example.com/push/
PUSH_SUBSCRIPTION_KEYS_P256DH=BEpPCn0cfs3P0E0fY-gyOuahx5dW5N8qu
PUSH_SUBSCRIPTION_KEYS_AUTH=T5bhIIyre5TDC

Firebase Crashlytics

On/Off via .env. Firebase Core integration is required

CRASHLYTICS_ENABLED=false

Used to catch errors on client-side with error description and stackTrace

You should enable Firebase support and change config variable in .env file to enable crash reporting

Versioning

Android

Uses version from pubspec.yaml

iOS

By default Flutter project config it should use version from pubspec.yaml, However, sometimes it causes strange iOS build errors(version is not changed but should be).

So, Fedi requires a manual increasing version code & name in Runner and Share Extension targets.

Receiving share intents & ShareExtension

XCode project has additional ShareExtension module required by receive_sharing_intent to handle income share events. It is also important to add Target and ShareExtension to the same group ID.

3rd Party

Thanks