Commit 4eae4bea authored by mgabdev's avatar mgabdev

Initial commit

open_collective: tusky
\ No newline at end of file
# Contributing
## Getting Started
1. Fork the repository on the GitHub page by clicking the Fork button. This makes a fork of the project under your GitHub account.
2. Clone your fork to your machine. ```git clone<Your_Username>/Tusky```
3. Create a new branch named after your change. ```git checkout -b your-change-name``` (```checkout``` switches to a branch, ```-b``` specifies that the branch is a new one)
## Making Changes
### Text
All English text that will be visible to users should be put in ```app/src/main/res/values/strings.xml```. Any text that is missing in a translation will fall back to the version in this file. Be aware that anything added to this file will need to be translated, so be very concise with wording and try to add as few things as possible. Look for existing strings to use first. If there is untranslatable text that you don't want to keep as a string constant in a Java class, you can use the string resource file ```app/src/main/res/values/donottranslate.xml```.
### Translation
Translations are done through .
To add a new language, clic on the 'Start a new translation' button on at the bottom of the page.
### Kotlin
This project is in the process of migrating to Kotlin, we prefer new code to be written in Kotlin. We try to follow the [Kotlin Style Guide]( and make use of the [Kotlin Android Extensions](
### Java
Existing code in Java should follow the [Android Style Guide](, which is what Android uses for their own source code. ```@Nullable``` and ```@NotNull``` annotations are really helpful for Kotlin interoperability.
### Visuals
There are three themes in the app, so any visual changes should be checked with each of them to ensure they look appropriate no matter which theme is selected. Usually, you can use existing color attributes like ```?attr/colorPrimary``` and ```?attr/textColorSecondary```. For icons and drawables, use a white drawable and tint it at runtime using ```ThemeUtils``` and specify an attribute that references different colours depending on the theme.
### Saving
Any time you get a good chunk of work done it's good to make a commit. You can either uses Android Studio's built-in UI for doing this or running the commands:
git add .
git commit -m "Describe the changes in this commit here."
## Submitting Your Changes
1. Make sure your branch is up-to-date with the ```master``` branch. Run:
git fetch
git rebase origin/master
It may refuse to start the rebase if there's changes that haven't been committed, so make sure you've added and committed everything. If there were changes on master to any of the parts of files you worked on, a conflict will arise when you rebase. [Resolving a merge conflict]( is a good guide to help with this. After committing the resolution, you can run ```git rebase --continue``` to finish the rebase. If you want to cancel, like if you make some mistake in resolving the conflict, you can always do ```git rebase --abort```.
2. Push your local branch to your fork on GitHub by running ```git push origin your-change-name```.
3. Then, go to the original project page and make a pull request. Select your fork/branch and use ```master``` as the base branch.
4. Wait for feedback on your pull request and be ready to make some changes
If you have any questions, don't hesitate to open an issue or contact []( Please also ask before you start implementing a new big feature.
[Issue text goes here].
* * * *
- Tusky Version:
- Android Version:
- Android Device:
- Mastodon instance (if applicable):
- [ ] I searched or browsed the repo’s other issues to ensure this is not a duplicate.
This diff is collapsed.
# Gab
Gab is a beautiful Android client for GNU social-compatible federated social networks. That means not one entity controls the whole network, rather, like e-mail, volunteers and organisations operate their own independent servers, users from which can all interact with each other seamlessly.
[<img src="" alt="Get it on Google Play" height="80" />](
## Features
- Material Design
- Most Mastodon APIs implemented
- Multi-Account support
- Dark, light and black themes with the possibility to auto-switch based on the time of day
- Drafts - compose toots and save them for later
- Choose between different emoji styles
- Optimized for all screen sizes
- Completely open-source - no non-free dependencies like Google services
### Gab is a modification of Tusky, created on 7/7//2019. [Original project repo](
apply plugin: ''
apply plugin: 'kotlin-android'
apply plugin: 'kotlin-android-extensions'
apply plugin: 'kotlin-kapt'
def getGitSha = { ->
def stdout = new ByteArrayOutputStream()
exec {
commandLine 'git', 'rev-parse', '--short', 'HEAD'
standardOutput = stdout
return stdout.toString().trim()
android {
compileSdkVersion 28
defaultConfig {
applicationId "com.gabai.gabby"
minSdkVersion 21
targetSdkVersion 28
versionCode 66
versionName "8.0.2"
testInstrumentationRunner "androidx.test.runner.AndroidJUnitRunner"
vectorDrawables.useSupportLibrary = true
kapt {
arguments {
arg("room.schemaLocation", "$projectDir/schemas")
buildTypes {
release {
minifyEnabled true
shrinkResources true
proguardFiles ''
debug {}
flavorDimensions "color"
productFlavors {
blue {}
green {
applicationIdSuffix ".test"
versionNameSuffix "-" + getGitSha()
lintOptions {
disable 'MissingTranslation'
compileOptions {
sourceCompatibility JavaVersion.VERSION_1_8
targetCompatibility JavaVersion.VERSION_1_8
androidExtensions {
experimental = true
testOptions {
unitTests {
includeAndroidResources = true
sourceSets {
androidTest.assets.srcDirs += files("$projectDir/schemas".toString())
packagingOptions {
// Exclude unneeded files added by libraries
exclude 'LICENSE_OFL'
bundle {
language {
// bundle all languages in every apk so the dynamic language switching works
enableSplit = false
project.tasks.withType(org.jetbrains.kotlin.gradle.tasks.KotlinCompile).all {
kotlinOptions {
jvmTarget = "1.8"
ext.daggerVersion = '2.23.1'
ext.retrofitVersion = '2.6.0'
// if libraries are changed here, they should also be changed in LicenseActivity
dependencies {
implementation('com.mikepenz:materialdrawer:6.1.2@aar') {
transitive = true
implementation 'androidx.core:core:1.0.2'
implementation 'androidx.appcompat:appcompat:1.0.2'
implementation 'androidx.browser:browser:1.0.0'
implementation 'androidx.recyclerview:recyclerview:1.0.0'
implementation 'androidx.legacy:legacy-support-v13:1.0.0'
implementation ''
implementation 'androidx.exifinterface:exifinterface:1.0.0'
implementation 'androidx.cardview:cardview:1.0.0'
implementation 'androidx.preference:preference:1.1.0-alpha04'
implementation "com.squareup.retrofit2:retrofit:$retrofitVersion"
implementation "com.squareup.retrofit2:converter-gson:$retrofitVersion"
implementation "com.squareup.retrofit2:adapter-rxjava2:$retrofitVersion"
implementation 'com.squareup.okhttp3:okhttp:3.14.2'
implementation 'com.squareup.okhttp3:logging-interceptor:3.14.2'
implementation 'org.conscrypt:conscrypt-android:2.1.0'
implementation 'com.github.connyduck:sparkbutton:2.0.0'
implementation 'com.github.chrisbanes:PhotoView:2.3.0'
implementation 'com.mikepenz:google-material-typeface:'
implementation('com.theartofdev.edmodo:android-image-cropper:2.8.0') {
exclude group: ''
implementation 'com.evernote:android-job:1.2.6'
implementation 'androidx.constraintlayout:constraintlayout:1.1.3'
// EmojiCompat
implementation 'androidx.emoji:emoji:1.0.0'
implementation 'androidx.emoji:emoji-appcompat:1.0.0'
implementation 'de.c1710:filemojicompat:1.0.17'
// architecture components
implementation 'androidx.lifecycle:lifecycle-extensions:2.0.0'
implementation ''
implementation 'androidx.legacy:legacy-support-v4:1.0.0'
kapt ''
implementation ''
implementation "org.jetbrains.kotlin:kotlin-stdlib-jdk8:$kotlin_version"
implementation "$daggerVersion"
kapt "$daggerVersion"
implementation "$daggerVersion"
implementation "$daggerVersion"
kapt "$daggerVersion"
testImplementation 'org.robolectric:robolectric:4.3'
testImplementation 'org.mockito:mockito-inline:2.28.2'
testImplementation 'com.nhaarman.mockitokotlin2:mockito-kotlin:2.1.0'
androidTestImplementation('androidx.test.espresso:espresso-core:3.1.1', {
exclude group: '', module: 'support-annotations'
androidTestImplementation ''
androidTestImplementation 'androidx.test.ext:junit:1.1.1'
testImplementation 'androidx.test.ext:junit:1.1.1'
debugImplementation 'im.dino:dbinspector:3.4.1@aar'
implementation 'io.reactivex.rxjava2:rxjava:2.2.9'
implementation 'io.reactivex.rxjava2:rxandroid:2.1.1'
implementation 'io.reactivex.rxjava2:rxkotlin:2.3.0'
implementation 'com.uber.autodispose:autodispose-android-archcomponents:1.3.0'
implementation 'com.uber.autodispose:autodispose:1.3.0'
implementation 'androidx.paging:paging-runtime-ktx:2.1.0'
implementation 'com.github.bumptech.glide:glide:4.9.0'
implementation 'com.github.bumptech.glide:okhttp3-integration:4.9.0'
implementation 'jp.wasabeef:glide-transformations:3.1.1' // intentionally use 3.x version because of 2mb smaller apk
//Add some useful extensions
implementation 'androidx.core:core-ktx:1.2.0-alpha01'
# turn on all optimizations except those that are known to cause problems on Android
-optimizations !code/simplification/cast,!field/*,!class/merging/*
-optimizationpasses 6
-keepattributes *Annotation*
# For native methods, see
-keepclasseswithmembernames class * {
native <methods>;
# keep setters in Views so that animations can still work.
# see
-keepclassmembers public class * extends android.view.View {
void set*(***);
*** get*();
# We want to keep methods in Activity that could be used in the XML attribute onClick
-keepclassmembers class * extends {
public void *(android.view.View);
# For enumeration classes, see
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
-keepclassmembers class * implements android.os.Parcelable {
public static final android.os.Parcelable$Creator CREATOR;
-keepclassmembers class **.R$* {
public static <fields>;
# The support library contains references to newer platform versions.
# Don't warn about those in case this app is linking against an older
# platform version. We know about them, and they are safe.
## for okhttp
-dontwarn javax.annotation.**
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
-dontwarn org.codehaus.mojo.animal_sniffer.*
-dontwarn okhttp3.internal.platform.ConscryptPlatform
##for keep
-dontwarn android.arch.util.paging.CountedDataSource
## for retrofit
-dontwarn retrofit2.**
-keep class retrofit2.** { *; }
-keepattributes Signature
-keepattributes Exceptions
-keepattributes *Annotation*
-keepclasseswithmembers class * {
@retrofit2.http.* <methods>;
-keep class com.gabai.gabby.entity.** { *; }
-keep public enum com.gabai.gabby.entity.*$** {
**[] $VALUES;
public *;
# preserve line numbers for crash reporting
-keepattributes SourceFile,LineNumberTable
-renamesourcefileattribute SourceFile
# remove all logging from production apk
-assumenosideeffects class android.util.Log {
public static *** getStackTraceString(...);
public static *** d(...);
public static *** w(...);
public static *** v(...);
public static *** i(...);
# remove some kotlin overhead
-assumenosideeffects class kotlin.jvm.internal.Intrinsics {
static void checkParameterIsNotNull(java.lang.Object, java.lang.String);
static void checkExpressionValueIsNotNull(java.lang.Object, java.lang.String);
static void throwUninitializedPropertyAccessException(java.lang.String);
# without this emoji font downloading fails with AbstractMethodError
-keep class * extends android.os.AsyncTask {
public *;
# Glide
-keep public class * implements com.bumptech.glide.module.GlideModule
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
This diff is collapsed.
"formatVersion": 1,
"database": {
"version": 10,
"identityHash": "69e310ef98c0f305934d25e763ee0140",
"entities": [
"tableName": "TootEntity",
"createSql": "CREATE TABLE IF NOT EXISTS `${TABLE_NAME}` (`uid` INTEGER PRIMARY KEY AUTOINCREMENT NOT NULL, `text` TEXT, `urls` TEXT, `descriptions` TEXT, `contentWarning` TEXT, `inReplyToId` TEXT, `inReplyToText` TEXT, `inReplyToUsername` TEXT, `visibility` INTEGER)",
"fields": [
"fieldPath": "uid",
"columnName": "uid",
"affinity": "INTEGER",
"notNull": true
"fieldPath": "text",
"columnName": "text",
"affinity": "TEXT",
"notNull": false
"fieldPath": "urls",
"columnName": "urls",
"affinity": "TEXT",
"notNull": false
"fieldPath": "descriptions",
"columnName": "descriptions",
"affinity": "TEXT",
"notNull": false
"fieldPath": "contentWarning",
"columnName": "contentWarning",
"affinity": "TEXT",
"notNull": false
"fieldPath": "inReplyToId",
"columnName": "inReplyToId",
"affinity": "TEXT",
"notNull": false
"fieldPath": "inReplyToText",
"columnName": "inReplyToText",
"affinity": "TEXT",
"notNull": false
"fieldPath": "inReplyToUsername",
"columnName": "inReplyToUsername",
"affinity": "TEXT",
"notNull": false
"fieldPath": "visibility",
"columnName": "visibility",
"affinity": "INTEGER",
"notNull": false
"primaryKey": {
"columnNames": [