Add app-thunderbird module

This commit is contained in:
Wolf-Martell Montwé 2024-01-23 11:51:53 +01:00
parent 96e61edbd1
commit 5d24a61de0
No known key found for this signature in database
GPG key ID: 6D45B21512ACBF72
27 changed files with 1856 additions and 1 deletions

View file

@ -0,0 +1,3 @@
# Thunderbird for Android
This is the official source code of the Thunderbird Android app.

View file

@ -0,0 +1,92 @@
package: name='net.thunderbird.placeholder' versionCode='1' versionName='0.1-SNAPSHOT' platformBuildVersionName='14' platformBuildVersionCode='34' compileSdkVersion='34' compileSdkVersionCodename='14'
install-location:'auto'
sdkVersion:'21'
targetSdkVersion:'33'
uses-permission: name='android.permission.READ_CONTACTS'
uses-permission: name='android.permission.POST_NOTIFICATIONS'
uses-permission: name='android.permission.RECEIVE_BOOT_COMPLETED'
uses-permission: name='android.permission.READ_SYNC_SETTINGS'
uses-permission: name='android.permission.ACCESS_NETWORK_STATE'
uses-permission: name='android.permission.INTERNET'
uses-permission: name='android.permission.VIBRATE'
uses-permission: name='android.permission.WAKE_LOCK'
uses-permission: name='android.permission.FOREGROUND_SERVICE'
uses-permission: name='android.permission.FOREGROUND_SERVICE_DATA_SYNC'
uses-permission: name='android.permission.SCHEDULE_EXACT_ALARM'
uses-permission: name='android.permission.USE_BIOMETRIC'
uses-permission: name='android.permission.USE_FINGERPRINT'
uses-permission: name='net.thunderbird.placeholder.DYNAMIC_RECEIVER_NOT_EXPORTED_PERMISSION'
application-label:'Thunderbird'
application-label-ar:'Thunderbird'
application-label-be:'Thunderbird'
application-label-bg:'Thunderbird'
application-label-br:'Thunderbird'
application-label-ca:'Thunderbird'
application-label-cs:'Thunderbird'
application-label-cy:'Thunderbird'
application-label-da:'Thunderbird'
application-label-de:'Thunderbird'
application-label-el:'Thunderbird'
application-label-en:'Thunderbird'
application-label-en-GB:'Thunderbird'
application-label-eo:'Thunderbird'
application-label-es:'Thunderbird'
application-label-et:'Thunderbird'
application-label-eu:'Thunderbird'
application-label-fa:'Thunderbird'
application-label-fi:'Thunderbird'
application-label-fr:'Thunderbird'
application-label-fy:'Thunderbird'
application-label-gd:'Thunderbird'
application-label-gl:'Thunderbird'
application-label-hr:'Thunderbird'
application-label-hu:'Thunderbird'
application-label-in:'Thunderbird'
application-label-is:'Thunderbird'
application-label-it:'Thunderbird'
application-label-iw:'Thunderbird'
application-label-ja:'Thunderbird'
application-label-lt:'Thunderbird'
application-label-lv:'Thunderbird'
application-label-ml:'Thunderbird'
application-label-nb:'Thunderbird'
application-label-nl:'Thunderbird'
application-label-pl:'Thunderbird'
application-label-pt:'Thunderbird'
application-label-pt-BR:'Thunderbird'
application-label-pt-PT:'Thunderbird'
application-label-ro:'Thunderbird'
application-label-ru:'Thunderbird'
application-label-sk:'Thunderbird'
application-label-sl:'Thunderbird'
application-label-sq:'Thunderbird'
application-label-sr:'Thunderbird'
application-label-sv:'Thunderbird'
application-label-tr:'Thunderbird'
application-label-uk:'Thunderbird'
application-label-zh:'Thunderbird'
application-label-zh-CN:'Thunderbird'
application-label-zh-TW:'Thunderbird'
application-icon-120:'res/drawable-v26/ic_launcher.xml'
application-icon-160:'res/drawable-v26/ic_launcher.xml'
application-icon-240:'res/drawable-v26/ic_launcher.xml'
application-icon-320:'res/drawable-v26/ic_launcher.xml'
application-icon-480:'res/drawable-v26/ic_launcher.xml'
application-icon-640:'res/drawable-v26/ic_launcher.xml'
application-icon-65534:'res/drawable-v26/ic_launcher.xml'
application: label='Thunderbird' icon='res/drawable-v26/ic_launcher.xml'
uses-library-not-required:'com.sec.android.app.multiwindow'
launchable-activity: name='com.fsck.k9.activity.MessageList' label='' icon=''
uses-library-not-required:'androidx.window.extensions'
uses-library-not-required:'androidx.window.sidecar'
feature-group: label=''
uses-feature-not-required: name='android.hardware.touchscreen'
provides-component:'app-widget'
main
other-activities
other-receivers
other-services
supports-screens: 'small' 'normal' 'large' 'xlarge'
supports-any-density: 'true'
locales: '--_--' 'ar' 'be' 'bg' 'br' 'ca' 'cs' 'cy' 'da' 'de' 'el' 'en' 'en-GB' 'eo' 'es' 'et' 'eu' 'fa' 'fi' 'fr' 'fy' 'gd' 'gl' 'hr' 'hu' 'in' 'is' 'it' 'iw' 'ja' 'lt' 'lv' 'ml' 'nb' 'nl' 'pl' 'pt' 'pt-BR' 'pt-PT' 'ro' 'ru' 'sk' 'sl' 'sq' 'sr' 'sv' 'tr' 'uk' 'zh' 'zh-CN' 'zh-TW'
densities: '120' '160' '240' '320' '480' '640' '65534'

View file

@ -0,0 +1,161 @@
plugins {
id(ThunderbirdPlugins.App.androidCompose)
alias(libs.plugins.dependency.guard)
id("thunderbird.quality.badging")
}
val testCoverageEnabled: Boolean by extra
if (testCoverageEnabled) {
apply(plugin = "jacoco")
}
dependencies {
implementation(projects.app.common)
implementation(projects.core.ui.compose.theme2.thunderbird)
implementation(projects.feature.launcher)
implementation(projects.app.core)
implementation(projects.app.ui.legacy)
implementation(projects.app.ui.messageListWidget)
debugImplementation(projects.backend.demo)
implementation(libs.androidx.work.runtime)
testImplementation(libs.robolectric)
// Required for DependencyInjectionTest to be able to resolve OpenPgpApiManager
testImplementation(projects.plugins.openpgpApiLib.openpgpApi)
testImplementation(projects.feature.account.setup)
}
android {
namespace = "net.thunderbird.android"
defaultConfig {
applicationId = "net.thunderbird.placeholder"
testApplicationId = "net.thunderbird.placeholder.tests"
versionCode = 1
versionName = "0.1-SNAPSHOT"
// Keep in sync with the resource string array "supported_languages"
resourceConfigurations.addAll(
listOf(
"ar",
"be",
"bg",
"br",
"ca",
"cs",
"cy",
"da",
"de",
"el",
"en",
"en_GB",
"eo",
"es",
"et",
"eu",
"fa",
"fi",
"fr",
"fy",
"gd",
"gl",
"hr",
"hu",
"in",
"is",
"it",
"iw",
"ja",
"lt",
"lv",
"ml",
"nb",
"nl",
"pl",
"pt_BR",
"pt_PT",
"ro",
"ru",
"sk",
"sl",
"sq",
"sr",
"sv",
"tr",
"uk",
"zh_CN",
"zh_TW",
),
)
buildConfigField("String", "CLIENT_ID_APP_NAME", "\"Thunderbird\"")
}
signingConfigs {
if (project.hasProperty("thunderbird.keyAlias") &&
project.hasProperty("thunderbird.keyPassword") &&
project.hasProperty("thunderbird.storeFile") &&
project.hasProperty("thunderbird.storePassword")
) {
create("release") {
keyAlias = project.property("thunderbird.keyAlias") as String
keyPassword = project.property("thunderbird.keyPassword") as String
storeFile = file(project.property("thunderbird.storeFile") as String)
storePassword = project.property("thunderbird.storePassword") as String
}
}
}
buildTypes {
debug {
applicationIdSuffix = ".debug"
isMinifyEnabled = false
manifestPlaceholders["appAuthRedirectScheme"] = "net.thunderbird.placeholder.debug"
}
release {
signingConfig = signingConfigs.findByName("release")
isMinifyEnabled = true
isShrinkResources = true
manifestPlaceholders["appAuthRedirectScheme"] = "net.thunderbird.placeholder"
}
create("daily") {
initWith(getByName("release"))
applicationIdSuffix = ".daily"
matchingFallbacks += listOf("release")
manifestPlaceholders["appAuthRedirectScheme"] = "net.thunderbird.placeholder.daily"
}
create("beta") {
initWith(getByName("release"))
applicationIdSuffix = ".beta"
matchingFallbacks += listOf("release")
manifestPlaceholders["appAuthRedirectScheme"] = "net.thunderbird.placeholder.beta"
}
}
packaging {
jniLibs {
excludes += listOf("kotlin/**")
}
resources {
excludes += listOf(
"META-INF/*.kotlin_module",
"META-INF/*.version",
"kotlin/**",
"DebugProbesKt.bin",
)
}
}
}
dependencyGuard {
configuration("releaseRuntimeClasspath")
}

View file

@ -0,0 +1,200 @@
androidx.activity:activity-compose:1.8.2
androidx.activity:activity-ktx:1.8.2
androidx.activity:activity:1.8.2
androidx.annotation:annotation-experimental:1.4.0
androidx.annotation:annotation-jvm:1.7.1
androidx.annotation:annotation:1.7.1
androidx.appcompat:appcompat-resources:1.6.1
androidx.appcompat:appcompat:1.6.1
androidx.arch.core:core-common:2.2.0
androidx.arch.core:core-runtime:2.2.0
androidx.autofill:autofill:1.0.0
androidx.biometric:biometric:1.1.0
androidx.browser:browser:1.3.0
androidx.cardview:cardview:1.0.0
androidx.collection:collection-jvm:1.4.0
androidx.collection:collection-ktx:1.4.0
androidx.collection:collection:1.4.0
androidx.compose.animation:animation-android:1.6.5
androidx.compose.animation:animation-core-android:1.6.5
androidx.compose.animation:animation-core:1.6.5
androidx.compose.animation:animation:1.6.5
androidx.compose.foundation:foundation-android:1.6.5
androidx.compose.foundation:foundation-layout-android:1.6.5
androidx.compose.foundation:foundation-layout:1.6.5
androidx.compose.foundation:foundation:1.6.5
androidx.compose.material3:material3-android:1.2.1
androidx.compose.material3:material3:1.2.1
androidx.compose.material:material-android:1.6.5
androidx.compose.material:material-icons-core-android:1.6.5
androidx.compose.material:material-icons-core:1.6.5
androidx.compose.material:material-icons-extended-android:1.6.5
androidx.compose.material:material-icons-extended:1.6.5
androidx.compose.material:material-ripple-android:1.6.5
androidx.compose.material:material-ripple:1.6.5
androidx.compose.material:material:1.6.5
androidx.compose.runtime:runtime-android:1.6.5
androidx.compose.runtime:runtime-saveable-android:1.6.5
androidx.compose.runtime:runtime-saveable:1.6.5
androidx.compose.runtime:runtime:1.6.5
androidx.compose.ui:ui-android:1.6.5
androidx.compose.ui:ui-geometry-android:1.6.5
androidx.compose.ui:ui-geometry:1.6.5
androidx.compose.ui:ui-graphics-android:1.6.5
androidx.compose.ui:ui-graphics:1.6.5
androidx.compose.ui:ui-text-android:1.6.5
androidx.compose.ui:ui-text:1.6.5
androidx.compose.ui:ui-tooling-preview-android:1.6.5
androidx.compose.ui:ui-tooling-preview:1.6.5
androidx.compose.ui:ui-unit-android:1.6.5
androidx.compose.ui:ui-unit:1.6.5
androidx.compose.ui:ui-util-android:1.6.5
androidx.compose.ui:ui-util:1.6.5
androidx.compose.ui:ui:1.6.5
androidx.compose:compose-bom:2024.04.00
androidx.concurrent:concurrent-futures:1.1.0
androidx.constraintlayout:constraintlayout-core:1.0.4
androidx.constraintlayout:constraintlayout:2.1.4
androidx.coordinatorlayout:coordinatorlayout:1.2.0
androidx.core:core-ktx:1.12.0
androidx.core:core-splashscreen:1.0.1
androidx.core:core:1.12.0
androidx.cursoradapter:cursoradapter:1.0.0
androidx.customview:customview-poolingcontainer:1.0.0
androidx.customview:customview:1.1.0
androidx.documentfile:documentfile:1.0.0
androidx.drawerlayout:drawerlayout:1.1.1
androidx.dynamicanimation:dynamicanimation:1.0.0
androidx.emoji2:emoji2-views-helper:1.3.0
androidx.emoji2:emoji2:1.3.0
androidx.exifinterface:exifinterface:1.3.6
androidx.fragment:fragment-ktx:1.6.2
androidx.fragment:fragment:1.6.2
androidx.interpolator:interpolator:1.0.0
androidx.legacy:legacy-support-core-utils:1.0.0
androidx.lifecycle:lifecycle-common-java8:2.7.0
androidx.lifecycle:lifecycle-common:2.7.0
androidx.lifecycle:lifecycle-livedata-core-ktx:2.7.0
androidx.lifecycle:lifecycle-livedata-core:2.7.0
androidx.lifecycle:lifecycle-livedata-ktx:2.7.0
androidx.lifecycle:lifecycle-livedata:2.7.0
androidx.lifecycle:lifecycle-process:2.7.0
androidx.lifecycle:lifecycle-runtime-compose:2.7.0
androidx.lifecycle:lifecycle-runtime-ktx:2.7.0
androidx.lifecycle:lifecycle-runtime:2.7.0
androidx.lifecycle:lifecycle-service:2.7.0
androidx.lifecycle:lifecycle-viewmodel-compose:2.7.0
androidx.lifecycle:lifecycle-viewmodel-ktx:2.7.0
androidx.lifecycle:lifecycle-viewmodel-savedstate:2.7.0
androidx.lifecycle:lifecycle-viewmodel:2.7.0
androidx.loader:loader:1.0.0
androidx.localbroadcastmanager:localbroadcastmanager:1.1.0
androidx.navigation:navigation-common-ktx:2.7.7
androidx.navigation:navigation-common:2.7.7
androidx.navigation:navigation-compose:2.7.7
androidx.navigation:navigation-fragment:2.7.7
androidx.navigation:navigation-runtime-ktx:2.7.7
androidx.navigation:navigation-runtime:2.7.7
androidx.navigation:navigation-ui:2.7.7
androidx.preference:preference:1.2.1
androidx.print:print:1.0.0
androidx.profileinstaller:profileinstaller:1.3.0
androidx.recyclerview:recyclerview:1.3.2
androidx.resourceinspection:resourceinspection-annotation:1.0.1
androidx.room:room-common:2.5.0
androidx.room:room-ktx:2.5.0
androidx.room:room-runtime:2.5.0
androidx.savedstate:savedstate-ktx:1.2.1
androidx.savedstate:savedstate:1.2.1
androidx.slidingpanelayout:slidingpanelayout:1.2.0
androidx.sqlite:sqlite-framework:2.3.0
androidx.sqlite:sqlite:2.3.0
androidx.startup:startup-runtime:1.1.1
androidx.swiperefreshlayout:swiperefreshlayout:1.1.0
androidx.tracing:tracing:1.0.0
androidx.transition:transition:1.4.1
androidx.vectordrawable:vectordrawable-animated:1.1.0
androidx.vectordrawable:vectordrawable:1.1.0
androidx.versionedparcelable:versionedparcelable:1.1.1
androidx.viewpager2:viewpager2:1.1.0-beta02
androidx.viewpager:viewpager:1.0.0
androidx.window:window:1.0.0
androidx.work:work-runtime:2.9.0
co.touchlab:stately-concurrency-jvm:2.0.6
co.touchlab:stately-concurrency:2.0.6
co.touchlab:stately-concurrent-collections-jvm:2.0.6
co.touchlab:stately-concurrent-collections:2.0.6
co.touchlab:stately-strict-jvm:2.0.6
co.touchlab:stately-strict:2.0.6
com.beetstra.jutf7:jutf7:1.0.0
com.github.ByteHamster:SearchPreference:v2.3.0
com.github.bumptech.glide:annotations:4.16.0
com.github.bumptech.glide:disklrucache:4.16.0
com.github.bumptech.glide:gifdecoder:4.16.0
com.github.bumptech.glide:glide:4.16.0
com.google.android.flexbox:flexbox:3.0.0
com.google.android.material:material:1.11.0
com.google.errorprone:error_prone_annotations:2.15.0
com.google.guava:listenablefuture:1.0
com.jakewharton.timber:timber:5.0.1
com.jcraft:jzlib:1.0.7
com.mikepenz:fastadapter-extensions-drag:5.7.0
com.mikepenz:fastadapter-extensions-expandable:5.7.0
com.mikepenz:fastadapter-extensions-swipe:5.7.0
com.mikepenz:fastadapter-extensions-utils:5.7.0
com.mikepenz:fastadapter:5.7.0
com.mikepenz:materialdrawer:9.0.2
com.splitwise:tokenautocomplete:4.0.0-beta01
com.squareup.moshi:moshi:1.15.1
com.squareup.okhttp3:okhttp:4.12.0
com.squareup.okio:okio-jvm:3.9.0
com.squareup.okio:okio:3.9.0
com.takisoft.colorpicker:colorpicker:1.0.0
com.takisoft.datetimepicker:datetimepicker:1.0.2
com.takisoft.preferencex:preferencex-colorpicker:1.1.0
com.takisoft.preferencex:preferencex-datetimepicker:1.1.0
com.takisoft.preferencex:preferencex:1.1.0
commons-io:commons-io:2.16.1
de.cketti.library.changelog:ckchangelog-core:2.0.0-beta02
de.cketti.safecontentresolver:safe-content-resolver-v21:1.0.0
de.hdodenhof:circleimageview:3.1.0
io.insert-koin:koin-android:3.5.6
io.insert-koin:koin-androidx-compose:3.5.6
io.insert-koin:koin-bom:3.5.6
io.insert-koin:koin-compose-jvm:1.1.5
io.insert-koin:koin-compose:1.1.5
io.insert-koin:koin-core-jvm:3.5.6
io.insert-koin:koin-core:3.5.6
net.jcip:jcip-annotations:1.0
net.openid:appauth:0.11.1
org.apache.commons:commons-lang3:3.7
org.apache.commons:commons-text:1.3
org.apache.httpcomponents.client5:httpclient5:5.3.1
org.apache.httpcomponents.core5:httpcore5-h2:5.2.4
org.apache.httpcomponents.core5:httpcore5:5.2.4
org.apache.james:apache-mime4j-core:0.8.9
org.apache.james:apache-mime4j-dom:0.8.9
org.jetbrains.compose.runtime:runtime:1.5.12
org.jetbrains.kotlin:kotlin-android-extensions-runtime:1.9.23
org.jetbrains.kotlin:kotlin-bom:1.9.23
org.jetbrains.kotlin:kotlin-parcelize-runtime:1.9.23
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.23
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.23
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.23
org.jetbrains.kotlin:kotlin-stdlib:1.9.23
org.jetbrains.kotlinx:kotlinx-collections-immutable-jvm:0.3.7
org.jetbrains.kotlinx:kotlinx-collections-immutable:0.3.7
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.0
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0
org.jetbrains.kotlinx:kotlinx-coroutines-core:1.8.0
org.jetbrains.kotlinx:kotlinx-datetime-jvm:0.5.0
org.jetbrains.kotlinx:kotlinx-datetime:0.5.0
org.jetbrains:annotations:24.0.1
org.jsoup:jsoup:1.17.2
org.minidns:minidns-client:1.0.5
org.minidns:minidns-core:1.0.5
org.minidns:minidns-dnssec:1.0.5
org.minidns:minidns-hla:1.0.5
org.minidns:minidns-iterative-resolver:1.0.5
org.slf4j:slf4j-api:1.7.36

64
app-thunderbird/proguard-rules.pro vendored Normal file
View file

@ -0,0 +1,64 @@
# Add project specific ProGuard rules here.
-dontobfuscate
# Preserve the line number information for debugging stack traces.
-keepattributes SourceFile,LineNumberTable
# Library specific rules
-dontnote android.net.http.*
-dontnote org.apache.commons.codec.**
-dontnote org.apache.http.**
-dontnote com.squareup.moshi.**
-dontnote com.github.amlcurran.showcaseview.**
-dontnote de.cketti.safecontentresolver.**
-dontnote com.tokenautocomplete.**
-dontwarn okio.**
-dontwarn com.squareup.moshi.**
# Glide
-keep public class * extends com.bumptech.glide.module.AppGlideModule
-keep public class * extends com.bumptech.glide.module.LibraryGlideModule
-keep public enum com.bumptech.glide.load.ImageHeaderParser$** {
**[] $VALUES;
public *;
}
# Project specific rules
-dontnote com.fsck.k9.ui.messageview.**
-dontnote com.fsck.k9.view.**
-assumevalues class * extends android.view.View {
boolean isInEditMode() return false;
}
-keep public class org.openintents.openpgp.**
-keepclassmembers class * extends androidx.appcompat.widget.SearchView {
public <init>(android.content.Context);
}
-keep class com.fsck.k9.mail.oauth.XOAuth2Response { *; }
# okhttp rules
# see: https://github.com/square/okhttp/blob/master/okhttp/src/main/resources/META-INF/proguard/okhttp3.pro
# JSR 305 annotations are for embedding nullability information.
-dontwarn javax.annotation.**
# A resource is loaded with a relative path so the package of this class must be preserved.
-keepnames class okhttp3.internal.publicsuffix.PublicSuffixDatabase
# Animal Sniffer compileOnly dependency to ensure APIs are compatible with older versions of Java.
-dontwarn org.codehaus.mojo.animal_sniffer.*
# OkHttp platform used only on JVM and when Conscrypt dependency is available.
-dontwarn okhttp3.internal.platform.ConscryptPlatform
-dontwarn kotlinx.serialization.KSerializer
-dontwarn kotlinx.serialization.Serializable
-dontwarn org.apache.http.client.methods.CloseableHttpResponse
-dontwarn org.slf4j.impl.StaticLoggerBinder
-keep,allowshrinking class com.tokenautocomplete.TokenCompleteTextView

View file

@ -0,0 +1,11 @@
package net.thunderbird.android.dev
import com.fsck.k9.backend.BackendFactory
import org.koin.core.module.Module
import org.koin.core.qualifier.named
fun Module.developmentModuleAdditions() {
single<Map<String, BackendFactory>>(named("developmentBackends")) {
emptyMap()
}
}

View file

@ -0,0 +1,269 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="72dp"
android:height="72dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#008787"
android:pathData="M866.3,634H493.4C482.5,634 473.6,642.9 473.6,653.8V713.5C473.6,801.4 544.8,872.6 632.6,872.6H839C904.8,872.6 958.3,819.2 958.3,753.3V701.1C958.3,671.2 928.4,634 866.3,634Z" />
<path android:pathData="M441,259.7H441.1C467.8,166.5 584,121 702.4,121C784.2,121 857.7,146.9 908,188C878,189.4 848.3,195.3 820,205.5C860.7,220.7 895.6,243.9 921.5,272.7C902,269.3 882.2,267.8 862.4,268.2C911.1,338.8 937.1,422.6 937,508.4C937,742.3 747.4,931.9 513.5,931.9C283.2,931.9 90,739.1 90,508.4C90,472 94.8,434.3 104.2,399.1C106.7,391.6 110.1,384.5 114.7,381.9C120.4,378.7 125.6,388.4 126.5,391.6C132.6,414.7 141,437.3 151.3,459C150.4,410.6 171.1,366.6 199.5,328.5C218.5,303.1 236,279.6 244.1,211.6C244.7,207.1 249,203.8 253.4,205.2C315,225.4 348,328.1 342.9,413.9C376.9,418.8 376.8,383.2 376.8,383.2C365.9,349.8 373.1,287.6 440.9,259.7H441Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="834"
android:endY="817.4"
android:startX="237"
android:startY="260.6"
android:type="linear">
<item
android:color="#FF1B91F3"
android:offset="0" />
<item
android:color="#FF0B68CB"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path
android:fillAlpha="0.9"
android:pathData="M923.1,400.5C933.4,633.5 742,834.3 508.5,834.3C289.9,834.3 110.8,665.3 94.6,450.9C91.7,471 90.2,491.2 90,511.5C91.7,741 284.4,931.9 513.5,931.9C747.4,931.9 937,742.3 937,508.4C937,471.1 932.2,435 923.1,400.5Z"
android:strokeAlpha="0.9">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="235.9"
android:centerY="452.2"
android:gradientRadius="358.1"
android:type="radial">
<item
android:color="#000B4186"
android:offset="0.5" />
<item
android:color="#720B4186"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M503.2,290.6C498.6,282.5 477.5,270.6 468.3,268.5C503.2,156.9 680.7,122.6 789.4,142.4C834.6,150.6 890.9,175.2 908,188C857.7,146.9 784.2,121 702.4,121C584,121 467.8,166.5 441.1,259.7H440.9C373.1,287.6 365.9,349.8 376.8,383.3C387.2,343.3 437,294.3 503.2,290.6Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="524.4"
android:centerY="305.1"
android:gradientRadius="76.6"
android:type="radial">
<item
android:color="#00B39BF6"
android:offset="0" />
<item
android:color="#E5B39BF6"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M626.2,213.5C531.1,232.2 500,238.4 468.2,268.6C503.9,174 595.2,154.8 704,197.9C678.1,203.3 652.2,208.5 626.2,213.5V213.5Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="617.9"
android:endY="164"
android:startX="403.1"
android:startY="403.1"
android:type="linear">
<item
android:color="#FF0F5DB0"
android:offset="0" />
<item
android:color="#000F5DB0"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M113,386.1C87,492.5 107.1,617.6 225.2,722.5C190,684.1 147.1,542.1 241.8,440.8C248.2,433.9 259.1,438.9 259.5,448.3C267.3,659 437.3,787.7 633.4,763.6C572.6,760.2 371.8,689.9 521.2,662C599.3,647.5 721.8,624.7 721.8,514.8C721.8,336.7 584,284.6 500.5,292.3C443.3,297.6 392.5,333.9 376.8,383.2C382.8,402.7 358.8,416.3 342.9,414C348,328.1 315,225.4 253.4,205.2C249,203.8 244.7,207.1 244.1,211.6C236,279.6 218.5,303.1 199.5,328.5C171.1,366.6 150.4,410.6 151.3,459C141,437.3 132.6,414.7 126.5,391.6C125.8,388.9 122,381.6 117.4,381.3C114.9,381.1 113.6,383.5 113,386.1Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="353.8"
android:centerY="739.1"
android:gradientRadius="558.7"
android:type="radial">
<item
android:color="#FF094188"
android:offset="0" />
<item
android:color="#000B4186"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M468.7,672.8C583.7,766.2 815,696.2 815,469.2C721.6,610.7 602.7,708.3 468.7,672.8H468.7Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="613.5"
android:endY="756.5"
android:startX="763.5"
android:startY="591"
android:type="linear">
<item
android:color="#00B39BF6"
android:offset="0" />
<item
android:color="#CCB39BF6"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M241.8,440.7C242.8,439.6 244.2,438.7 245.6,438.1C247.1,437.6 248.7,437.4 250.2,437.7C165.5,541 233.8,722.6 280.8,767.2C283.4,774.7 236.2,736 229.8,727C194.1,696.7 142.9,546.6 241.8,440.7Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="248.2"
android:endY="710.5"
android:startX="184"
android:startY="438"
android:type="linear">
<item
android:color="#FFB39BF6"
android:offset="0.1" />
<item
android:color="#00B39BF6"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M513.5,681.4C628.5,681.4 721.8,605.3 721.8,511.4C721.8,417.6 628.5,341.5 513.5,341.5C415.4,341.5 305.2,405.3 305.2,513.9C305.3,681.7 482.5,778.2 633.6,763.6C622.3,762.3 551.5,758.5 503.6,704.4C499.3,699.5 491.8,691 495.2,685.5C498.6,680 507.9,681.4 513.5,681.4L513.5,681.4Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="513.5"
android:endY="761.9"
android:startX="513.5"
android:startY="403.7"
android:type="linear">
<item
android:color="#FFFFFFFF"
android:offset="0" />
<item
android:color="#FFBEE1FE"
android:offset="0.9" />
<item
android:color="#FF96CEFD"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path
android:fillAlpha="0.7"
android:pathData="M722,511.9C722,605.7 628.8,681.8 513.8,681.8C508.2,681.8 498.9,680.4 495.5,685.9C492.1,691.4 499.6,700 503.9,704.8C548.9,755.7 614.1,762.1 631.2,763.8L633.9,764.1C482.8,778.7 305.5,682.1 305.5,514.4C305.3,486.4 313.1,459 327.9,435.3L490.2,582.7C501.7,593.1 521.1,593.1 532.7,582.7L698,432.5C713.4,456.2 722,483.2 722,511.9Z"
android:strokeAlpha="0.7">
<aapt:attr name="android:fillColor">
<gradient
android:endX="513.8"
android:endY="740.2"
android:startX="513.8"
android:startY="635.5"
android:type="linear">
<item
android:color="#FFBCE0FD"
android:offset="0" />
<item
android:color="#FF88CCFC"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path
android:fillAlpha="0.3"
android:fillColor="#0768BA"
android:pathData="M688,443.5L539.7,605.5C525.1,615.5 501.9,616.7 486.5,607.5L350.5,454.5C355.1,447.3 328.3,428.9 334,422.5L365,448C407.4,486.6 441.8,517.8 490.1,557.8C512,575.9 518.7,575.5 540.2,557.8C595.5,512 646.9,470.6 699.5,425C705.4,431.5 698.8,419.1 703.5,426.4L688,443.5Z" />
<path android:pathData="M698.6,433.4C698.4,433.1 698.2,432.8 698,432.5L532.7,582.7C521.1,593.1 501.7,593.1 490.2,582.7L327.9,435.3C327.8,435.1 327.8,435 327.7,434.8C364.9,375 442.4,341.5 513.5,341.5C594.1,341.5 663.9,378.8 698.6,433.4Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="513.1"
android:endY="750.5"
android:startX="513.1"
android:startY="378.1"
android:type="linear">
<item
android:color="#FFFFFFFF"
android:offset="0" />
<item
android:color="#FFBEE1FE"
android:offset="0.9" />
<item
android:color="#FF96CEFD"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#F2F9FF"
android:pathData="M699.1,434.2L534.5,591.7C519.9,602.1 504.3,602.9 489,593.5L327.5,434.8C332.1,427.4 337.3,420.4 343,413.8L360,429.6C402.4,469.4 436.6,501.5 485,542.7C506.8,561.3 513.5,560.9 534.9,542.7C590.2,495.5 630.6,459.8 683.2,412.9C689,419.6 694.3,426.7 699.1,434.2L699.1,434.2Z" />
<path
android:fillColor="#ffffff"
android:pathData="M542.7,256.5C565,249.5 563,227.4 563,227.4C563,227.4 551.9,214.3 529.8,221.5C509.1,228.4 505.9,243.1 505.9,243.1C505.9,243.1 517.2,264.5 542.7,256.5Z" />
<path
android:fillAlpha="0.9"
android:pathData="M866.3,634H493.4C482.5,634 473.6,642.9 473.6,653.8V713.5C473.6,801.4 544.8,872.6 632.6,872.6H839C904.8,872.6 958.3,819.2 958.3,753.3V701.1C958.3,671.2 928.4,634 866.3,634Z"
android:strokeAlpha="0.9">
<aapt:attr name="android:fillColor">
<gradient
android:endX="727.4"
android:endY="740.7"
android:startX="856.4"
android:startY="862.9"
android:type="linear">
<item
android:color="#7F054096"
android:offset="0" />
<item
android:color="#700F3D9C"
android:offset="0.1" />
<item
android:color="#3F2F35B1"
android:offset="0.3" />
<item
android:color="#1C462FBF"
android:offset="0.5" />
<item
android:color="#07542BC8"
android:offset="0.7" />
<item
android:color="#00592ACB"
android:offset="0.9" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M938.4,720.9H595.6C514.5,720.9 448.7,786.7 448.7,867.8V939.7C448.7,950.7 457.6,959.6 468.6,959.6H811.4C892.5,959.6 958.3,893.8 958.3,812.7V701.1C958.3,712 949.4,720.9 938.4,720.9Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="970.6"
android:endY="940"
android:startX="504.7"
android:startY="742.8"
android:type="linear">
<item
android:color="#FF54FFBD"
android:offset="0" />
<item
android:color="#FF00DDFF"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#20123A"
android:pathData="M537,790.9H578.2C600.2,790.9 612.7,800.9 612.7,818.7C612.8,822.8 611.8,826.9 609.8,830.4C607.8,834 604.8,836.9 601.2,838.9C609.5,843.1 614.2,850.6 614.2,861C614.2,880.6 600.5,890.4 578.4,890.4H537V790.9ZM555.9,808V831H578.8C589.1,831 593.4,825.9 593.4,819.1C593.4,812.2 588.6,808 578.6,808H555.9ZM555.9,848.3V873.1H578.7C589.2,873.1 594.7,868.3 594.7,860.6C594.7,852.8 590,848.3 577.9,848.3H555.9ZM632.5,790.9H699.5V809H651.8V831.4H699.5V849.5H651.8V872.2H699.5V890.4H632.5V790.9ZM743.7,808.6H716V790.9H790V808.6H762.6V890.4H743.6L743.7,808.6ZM822.6,790.9H841.5L879.2,890.4H859.4L852.8,872.3H811.3L804.7,890.4H785L822.6,790.9ZM817.7,854.8H846.4L832.1,815.3L817.7,854.8Z" />
</vector>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="tb_app_name" translatable="false">Thunderbird Beta</string>
</resources>

View file

@ -0,0 +1,11 @@
package net.thunderbird.android.dev
import com.fsck.k9.backend.BackendFactory
import org.koin.core.module.Module
import org.koin.core.qualifier.named
fun Module.developmentModuleAdditions() {
single<Map<String, BackendFactory>>(named("developmentBackends")) {
emptyMap()
}
}

View file

@ -0,0 +1,210 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="72dp"
android:height="72dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path android:pathData="M438.7,259.8H438.8C465.4,166.7 581.6,121.2 699.9,121.2C781.6,121.2 855,147.1 905.3,188.2C874.2,189.7 844.5,195.8 817.4,205.7C858,220.8 892.9,244 918.8,272.8C901.7,269.8 883.8,268.3 865.6,268.3C863.6,268.3 861.7,268.3 859.7,268.3C906.7,336.5 934.3,419.2 934.3,508.2C934.3,741.9 744.8,931.4 511.1,931.4C281.1,931.4 88,738.7 88,508.2C88,471.8 92.9,434.3 102.3,399C104.7,391.6 108.2,384.5 112.7,381.9C118.4,378.7 123.6,388.4 124.5,391.5C130.7,414.8 139,437.3 149.3,458.9C148.4,410.6 169.1,366.6 197.4,328.5C216.4,303.1 233.9,279.6 242,211.8C242.6,207.2 246.9,203.9 251.2,205.4C312.9,225.5 345.8,328.1 340.7,413.9C374.7,418.8 374.5,383.2 374.5,383.2C363.7,349.8 370.9,287.6 438.6,259.8H438.7Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="831.4"
android:endY="817"
android:startX="395.9"
android:startY="288"
android:type="linear">
<item
android:color="#FFF53DB8"
android:offset="0" />
<item
android:color="#FF590DF2"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path
android:fillAlpha="0.9"
android:pathData="M921.1,400.5C931.4,633.5 740,834.3 506.5,834.3C287.9,834.3 108.8,665.3 92.6,450.9C89.7,471 88.2,491.2 88,511.5C89.7,741 282.4,931.9 511.5,931.9C745.4,931.9 935,742.3 935,508.4C935,471.1 930.2,435 921.1,400.5Z"
android:strokeAlpha="0.9">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="233.9"
android:centerY="452.2"
android:gradientRadius="358.1"
android:type="radial">
<item
android:color="#000B4186"
android:offset="0.5" />
<item
android:color="#720B4186"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M501.2,290.6C496.6,282.5 475.5,270.6 466.3,268.5C501.2,156.9 678.7,122.6 787.4,142.4C832.6,150.6 888.9,175.2 906,188C855.7,146.9 782.2,121 700.4,121C582,121 465.8,166.5 439.1,259.7H438.9C371.1,287.6 363.9,349.8 374.8,383.3C385.2,343.3 435,294.3 501.2,290.6Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="522.4"
android:centerY="305.1"
android:gradientRadius="76.6"
android:type="radial">
<item
android:color="#00D13AEF"
android:offset="0" />
<item
android:color="#A3F9D286"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M624.2,213.5C529.1,232.2 498,238.4 466.2,268.6C501.9,174 593.2,154.8 702,197.9C676.1,203.3 650.2,208.5 624.2,213.5V213.5Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="615.9"
android:endY="164"
android:startX="401.1"
android:startY="403.1"
android:type="linear">
<item
android:color="#FF450FB0"
android:offset="0" />
<item
android:color="#00450FB0"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M111,386.1C85,492.5 105.1,617.6 223.2,722.5C188,684.1 145.1,542.1 239.8,440.8C246.2,433.9 257.1,438.9 257.5,448.3C265.3,659 435.3,787.7 631.4,763.6C570.6,760.2 369.8,689.9 519.2,662C597.3,647.5 719.8,624.7 719.8,514.8C719.8,336.7 582,284.6 498.5,292.3C441.3,297.6 390.5,333.9 374.8,383.2C380.8,402.7 356.8,416.3 340.9,414C346,328.1 313,225.4 251.4,205.2C247,203.8 242.7,207.1 242.1,211.6C234,279.6 216.5,303.1 197.5,328.5C169.1,366.6 148.4,410.6 149.3,459C139,437.3 130.6,414.7 124.5,391.6C123.8,388.9 120,381.6 115.4,381.3C112.9,381.1 111.6,383.5 111,386.1Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="351.8"
android:centerY="739.1"
android:gradientRadius="558.7"
android:type="radial">
<item
android:color="#FF650877"
android:offset="0" />
<item
android:color="#00340B86"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M466.7,672.8C581.7,766.2 813,696.2 813,469.2C719.6,610.7 600.7,708.3 466.7,672.8H466.7Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="611.5"
android:endY="756.5"
android:startX="761.5"
android:startY="591"
android:type="linear">
<item
android:color="#00D647E2"
android:offset="0" />
<item
android:color="#CCE7BB65"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M239.8,440.7C240.8,439.6 242.2,438.7 243.6,438.1C245.1,437.6 246.7,437.4 248.2,437.7C163.5,541 231.8,722.6 278.8,767.2C281.4,774.7 234.2,736 227.8,727C192.1,696.7 140.9,546.6 239.8,440.7Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="246.2"
android:endY="710.5"
android:startX="182"
android:startY="438"
android:type="linear">
<item
android:color="#FFF9BF86"
android:offset="0.1" />
<item
android:color="#00D63AEF"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M511.5,681.4C626.5,681.4 719.8,605.3 719.8,511.4C719.8,417.6 626.5,341.5 511.5,341.5C413.4,341.5 303.2,405.3 303.2,513.9C303.3,681.7 480.5,778.2 631.6,763.6C620.3,762.3 549.5,758.5 501.6,704.4C497.3,699.5 489.8,691 493.2,685.5C496.6,680 505.9,681.4 511.5,681.4L511.5,681.4Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="511.5"
android:endY="761.9"
android:startX="511.5"
android:startY="403.7"
android:type="linear">
<item
android:color="#FFFFFFFF"
android:offset="0" />
<item
android:color="#FFBEE1FE"
android:offset="0.9" />
<item
android:color="#FF96CEFD"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path
android:fillAlpha="0.7"
android:pathData="M720,511.9C720,605.7 626.8,681.8 511.8,681.8C506.2,681.8 496.9,680.4 493.5,685.9C490.1,691.4 497.6,700 501.9,704.8C546.9,755.7 612.1,762.1 629.2,763.8L631.9,764.1C480.8,778.7 303.5,682.1 303.5,514.4C303.3,486.4 311.1,459 325.9,435.3L488.2,582.7C499.7,593.1 519.1,593.1 530.7,582.7L696,432.5C711.4,456.2 720,483.2 720,511.9Z"
android:strokeAlpha="0.7">
<aapt:attr name="android:fillColor">
<gradient
android:endX="511.8"
android:endY="740.2"
android:startX="511.8"
android:startY="635.5"
android:type="linear">
<item
android:color="#FFBCE0FD"
android:offset="0" />
<item
android:color="#FF88CCFC"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path
android:fillAlpha="0.3"
android:fillColor="#0768BA"
android:pathData="M686,443.5L537.7,605.5C523.1,615.5 499.9,616.7 484.5,607.5L348.5,454.5C353.1,447.3 326.3,428.9 332,422.5L363,448C405.4,486.6 439.8,517.8 488.1,557.8C510,575.9 516.7,575.5 538.2,557.8C593.5,512 644.9,470.6 697.5,425C703.4,431.5 696.8,419.1 701.5,426.4L686,443.5Z" />
<path android:pathData="M696.6,433.4C696.4,433.1 696.2,432.8 696,432.5L530.7,582.7C519.1,593.1 499.7,593.1 488.2,582.7L325.9,435.3C325.8,435.1 325.8,435 325.7,434.8C362.9,375 440.4,341.5 511.5,341.5C592.1,341.5 661.9,378.8 696.6,433.4Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="511.1"
android:endY="750.5"
android:startX="511.1"
android:startY="378.1"
android:type="linear">
<item
android:color="#FFFFFFFF"
android:offset="0" />
<item
android:color="#FFBEE1FE"
android:offset="0.9" />
<item
android:color="#FF96CEFD"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#F2F9FF"
android:pathData="M697.1,434.2L532.5,591.7C517.9,602.1 502.3,602.9 487,593.5L325.5,434.8C330.1,427.4 335.3,420.4 341,413.8L358,429.6C400.4,469.4 434.6,501.5 483,542.7C504.8,561.3 511.5,560.9 532.9,542.7C588.2,495.5 628.6,459.8 681.2,412.9C687,419.6 692.3,426.7 697.1,434.2L697.1,434.2Z" />
<path
android:fillColor="#ffffff"
android:pathData="M540.7,256.5C563,249.5 561,227.4 561,227.4C561,227.4 549.9,214.3 527.8,221.5C507.1,228.4 503.9,243.1 503.9,243.1C503.9,243.1 515.2,264.5 540.7,256.5Z" />
</vector>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="tb_app_name" translatable="false">Thunderbird Daily</string>
</resources>

View file

@ -0,0 +1,12 @@
package net.thunderbird.android.dev
import com.fsck.k9.backend.BackendFactory
import org.koin.core.module.Module
import org.koin.core.qualifier.named
fun Module.developmentModuleAdditions() {
single { DemoBackendFactory(backendStorageFactory = get()) }
single<Map<String, BackendFactory>>(named("developmentBackends")) {
mapOf("demo" to get<DemoBackendFactory>())
}
}

View file

@ -0,0 +1,14 @@
package net.thunderbird.android.dev
import app.k9mail.backend.demo.DemoBackend
import com.fsck.k9.Account
import com.fsck.k9.backend.BackendFactory
import com.fsck.k9.backend.api.Backend
import com.fsck.k9.mailstore.K9BackendStorageFactory
class DemoBackendFactory(private val backendStorageFactory: K9BackendStorageFactory) : BackendFactory {
override fun createBackend(account: Account): Backend {
val backendStorage = backendStorageFactory.createBackendStorage(account)
return DemoBackend(backendStorage)
}
}

View file

@ -0,0 +1,269 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="72dp"
android:height="72dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path
android:fillColor="#008787"
android:pathData="M867.3,634H494.4C483.5,634 474.6,642.9 474.6,653.8V713.5C474.6,801.4 545.8,872.6 633.6,872.6H840C905.8,872.6 959.3,819.2 959.3,753.3V701.1C959.3,671.2 929.4,634 867.3,634Z" />
<path android:pathData="M438.7,259.8H438.8C465.4,166.7 581.6,121.2 699.9,121.2C781.6,121.2 855,147.1 905.3,188.2C874.2,189.7 844.5,195.8 817.4,205.7C858,220.8 892.9,244 918.8,272.8C901.7,269.8 883.8,268.3 865.6,268.3C863.6,268.3 861.7,268.3 859.7,268.3C906.7,336.5 934.3,419.2 934.3,508.2C934.3,741.9 744.8,931.4 511.1,931.4C281.1,931.4 88,738.7 88,508.2C88,471.8 92.9,434.3 102.3,399C104.7,391.6 108.2,384.5 112.7,381.9C118.4,378.7 123.6,388.4 124.5,391.5C130.7,414.8 139,437.3 149.3,458.9C148.4,410.6 169.1,366.6 197.4,328.5C216.4,303.1 233.9,279.6 242,211.8C242.6,207.2 246.9,203.9 251.2,205.4C312.9,225.5 345.8,328.1 340.7,413.9C374.7,418.8 374.5,383.2 374.5,383.2C363.7,349.8 370.9,287.6 438.6,259.8H438.7Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="831.4"
android:endY="817"
android:startX="395.9"
android:startY="288"
android:type="linear">
<item
android:color="#FFF53DB8"
android:offset="0" />
<item
android:color="#FF590DF2"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path
android:fillAlpha="0.9"
android:pathData="M921.1,400.5C931.4,633.5 740,834.3 506.5,834.3C287.9,834.3 108.8,665.3 92.6,450.9C89.7,471 88.2,491.2 88,511.5C89.7,741 282.4,931.9 511.5,931.9C745.4,931.9 935,742.3 935,508.4C935,471.1 930.2,435 921.1,400.5Z"
android:strokeAlpha="0.9">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="233.9"
android:centerY="452.2"
android:gradientRadius="358.1"
android:type="radial">
<item
android:color="#000B4186"
android:offset="0.5" />
<item
android:color="#720B4186"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M501.2,290.6C496.6,282.5 475.5,270.6 466.3,268.5C501.2,156.9 678.7,122.6 787.4,142.4C832.6,150.6 888.9,175.2 906,188C855.7,146.9 782.2,121 700.4,121C582,121 465.8,166.5 439.1,259.7H438.9C371.1,287.6 363.9,349.8 374.8,383.3C385.2,343.3 435,294.3 501.2,290.6Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="522.4"
android:centerY="305.1"
android:gradientRadius="76.6"
android:type="radial">
<item
android:color="#00D13AEF"
android:offset="0" />
<item
android:color="#A3F9D286"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M624.2,213.5C529.1,232.2 498,238.4 466.2,268.6C501.9,174 593.2,154.8 702,197.9C676.1,203.3 650.2,208.5 624.2,213.5V213.5Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="615.9"
android:endY="164"
android:startX="401.1"
android:startY="403.1"
android:type="linear">
<item
android:color="#FF450FB0"
android:offset="0" />
<item
android:color="#00450FB0"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M111,386.1C85,492.5 105.1,617.6 223.2,722.5C188,684.1 145.1,542.1 239.8,440.8C246.2,433.9 257.1,438.9 257.5,448.3C265.3,659 435.3,787.7 631.4,763.6C570.6,760.2 369.8,689.9 519.2,662C597.3,647.5 719.8,624.7 719.8,514.8C719.8,336.7 582,284.6 498.5,292.3C441.3,297.6 390.5,333.9 374.8,383.2C380.8,402.7 356.8,416.3 340.9,414C346,328.1 313,225.4 251.4,205.2C247,203.8 242.7,207.1 242.1,211.6C234,279.6 216.5,303.1 197.5,328.5C169.1,366.6 148.4,410.6 149.3,459C139,437.3 130.6,414.7 124.5,391.6C123.8,388.9 120,381.6 115.4,381.3C112.9,381.1 111.6,383.5 111,386.1Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="351.8"
android:centerY="739.1"
android:gradientRadius="558.7"
android:type="radial">
<item
android:color="#FF650877"
android:offset="0" />
<item
android:color="#00340B86"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M466.7,672.8C581.7,766.2 813,696.2 813,469.2C719.6,610.7 600.7,708.3 466.7,672.8H466.7Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="611.5"
android:endY="756.5"
android:startX="761.5"
android:startY="591"
android:type="linear">
<item
android:color="#00D647E2"
android:offset="0" />
<item
android:color="#CCE7BB65"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M239.8,440.7C240.8,439.6 242.2,438.7 243.6,438.1C245.1,437.6 246.7,437.4 248.2,437.7C163.5,541 231.8,722.6 278.8,767.2C281.4,774.7 234.2,736 227.8,727C192.1,696.7 140.9,546.6 239.8,440.7Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="246.2"
android:endY="710.5"
android:startX="182"
android:startY="438"
android:type="linear">
<item
android:color="#FFF9BF86"
android:offset="0.1" />
<item
android:color="#00D63AEF"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M511.5,681.4C626.5,681.4 719.8,605.3 719.8,511.4C719.8,417.6 626.5,341.5 511.5,341.5C413.4,341.5 303.2,405.3 303.2,513.9C303.3,681.7 480.5,778.2 631.6,763.6C620.3,762.3 549.5,758.5 501.6,704.4C497.3,699.5 489.8,691 493.2,685.5C496.6,680 505.9,681.4 511.5,681.4L511.5,681.4Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="511.5"
android:endY="761.9"
android:startX="511.5"
android:startY="403.7"
android:type="linear">
<item
android:color="#FFFFFFFF"
android:offset="0" />
<item
android:color="#FFBEE1FE"
android:offset="0.9" />
<item
android:color="#FF96CEFD"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path
android:fillAlpha="0.7"
android:pathData="M720,511.9C720,605.7 626.8,681.8 511.8,681.8C506.2,681.8 496.9,680.4 493.5,685.9C490.1,691.4 497.6,700 501.9,704.8C546.9,755.7 612.1,762.1 629.2,763.8L631.9,764.1C480.8,778.7 303.5,682.1 303.5,514.4C303.3,486.4 311.1,459 325.9,435.3L488.2,582.7C499.7,593.1 519.1,593.1 530.7,582.7L696,432.5C711.4,456.2 720,483.2 720,511.9Z"
android:strokeAlpha="0.7">
<aapt:attr name="android:fillColor">
<gradient
android:endX="511.8"
android:endY="740.2"
android:startX="511.8"
android:startY="635.5"
android:type="linear">
<item
android:color="#FFBCE0FD"
android:offset="0" />
<item
android:color="#FF88CCFC"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path
android:fillAlpha="0.3"
android:fillColor="#0768BA"
android:pathData="M686,443.5L537.7,605.5C523.1,615.5 499.9,616.7 484.5,607.5L348.5,454.5C353.1,447.3 326.3,428.9 332,422.5L363,448C405.4,486.6 439.8,517.8 488.1,557.8C510,575.9 516.7,575.5 538.2,557.8C593.5,512 644.9,470.6 697.5,425C703.4,431.5 696.8,419.1 701.5,426.4L686,443.5Z" />
<path android:pathData="M696.6,433.4C696.4,433.1 696.2,432.8 696,432.5L530.7,582.7C519.1,593.1 499.7,593.1 488.2,582.7L325.9,435.3C325.8,435.1 325.8,435 325.7,434.8C362.9,375 440.4,341.5 511.5,341.5C592.1,341.5 661.9,378.8 696.6,433.4Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="511.1"
android:endY="750.5"
android:startX="511.1"
android:startY="378.1"
android:type="linear">
<item
android:color="#FFFFFFFF"
android:offset="0" />
<item
android:color="#FFBEE1FE"
android:offset="0.9" />
<item
android:color="#FF96CEFD"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#F2F9FF"
android:pathData="M697.1,434.2L532.5,591.7C517.9,602.1 502.3,602.9 487,593.5L325.5,434.8C330.1,427.4 335.3,420.4 341,413.8L358,429.6C400.4,469.4 434.6,501.5 483,542.7C504.8,561.3 511.5,560.9 532.9,542.7C588.2,495.5 628.6,459.8 681.2,412.9C687,419.6 692.3,426.7 697.1,434.2L697.1,434.2Z" />
<path
android:fillColor="#ffffff"
android:pathData="M540.7,256.5C563,249.5 561,227.4 561,227.4C561,227.4 549.9,214.3 527.8,221.5C507.1,228.4 503.9,243.1 503.9,243.1C503.9,243.1 515.2,264.5 540.7,256.5Z" />
<path
android:fillAlpha="0.9"
android:pathData="M867.3,634H494.4C483.5,634 474.6,642.9 474.6,653.8V713.5C474.6,801.4 545.8,872.6 633.6,872.6H840C905.8,872.6 959.3,819.2 959.3,753.3V701.1C959.3,671.2 929.4,634 867.3,634Z"
android:strokeAlpha="0.9">
<aapt:attr name="android:fillColor">
<gradient
android:endX="728.4"
android:endY="740.7"
android:startX="857.4"
android:startY="862.9"
android:type="linear">
<item
android:color="#7F054096"
android:offset="0" />
<item
android:color="#700F3D9C"
android:offset="0.1" />
<item
android:color="#3F2F35B1"
android:offset="0.3" />
<item
android:color="#1C462FBF"
android:offset="0.5" />
<item
android:color="#07542BC8"
android:offset="0.7" />
<item
android:color="#00592ACB"
android:offset="0.9" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M939.4,720.9H596.6C515.5,720.9 449.7,786.7 449.7,867.8V939.7C449.7,950.7 458.6,959.6 469.6,959.6H812.4C893.5,959.6 959.3,893.8 959.3,812.7V701.1C959.3,712 950.4,720.9 939.4,720.9Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="971.6"
android:endY="940"
android:startX="505.7"
android:startY="742.8"
android:type="linear">
<item
android:color="#FF54FFBD"
android:offset="0" />
<item
android:color="#FF00DDFF"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#000000"
android:pathData="M526.1,889H493.1V795.9H526.4C535.7,795.9 543.8,797.8 550.5,801.5C557.3,805.2 562.5,810.5 566.1,817.5C569.8,824.4 571.6,832.7 571.6,842.4C571.6,852.1 569.8,860.4 566.1,867.4C562.5,874.3 557.3,879.7 550.5,883.4C543.7,887.1 535.5,889 526.1,889ZM512.8,872.1H525.3C531.1,872.1 536,871.1 540,869C544,867 547,863.7 549,859.4C551,855 552,849.3 552,842.4C552,835.5 551,829.9 549,825.5C547,821.1 544,817.9 540,815.9C536,813.8 531.1,812.8 525.3,812.8H512.8V872.1ZM586.2,889V795.9H648.9V812.1H605.9V834.3H645.7V850.5H605.9V872.8H649.1V889H586.2ZM664.6,889V795.9H701.9C708.7,795.9 714.4,796.9 719,799C723.6,801 727,803.8 729.3,807.4C731.6,811 732.8,815.1 732.8,819.8C732.8,823.4 732,826.6 730.6,829.4C729.1,832.1 727.1,834.3 724.6,836.1C722.1,837.8 719.2,839 716,839.8V840.7C719.5,840.8 722.8,841.8 725.9,843.7C729,845.5 731.6,848.1 733.5,851.5C735.4,854.8 736.4,858.7 736.4,863.3C736.4,868.2 735.2,872.6 732.7,876.5C730.3,880.3 726.7,883.4 722,885.6C717.2,887.9 711.3,889 704.4,889H664.6ZM684.3,872.9H700.3C705.8,872.9 709.8,871.9 712.3,869.8C714.8,867.7 716.1,864.8 716.1,861.3C716.1,858.7 715.5,856.5 714.2,854.5C713,852.5 711.2,851 708.9,849.9C706.6,848.7 703.9,848.2 700.8,848.2H684.3V872.9ZM684.3,834.9H698.9C701.6,834.9 704,834.4 706,833.5C708.2,832.5 709.8,831.1 711,829.4C712.3,827.6 712.9,825.5 712.9,823C712.9,819.7 711.7,817 709.3,814.9C707,812.8 703.6,811.8 699.2,811.8H684.3V834.9ZM806.7,795.9H826.4V856.4C826.4,863.2 824.8,869.1 821.5,874.2C818.3,879.3 813.8,883.2 808,886.1C802.2,888.9 795.5,890.3 787.8,890.3C780.1,890.3 773.3,888.9 767.5,886.1C761.7,883.2 757.2,879.3 754,874.2C750.8,869.1 749.2,863.2 749.2,856.4V795.9H768.9V854.7C768.9,858.2 769.7,861.4 771.2,864.1C772.8,866.9 775,869.1 777.9,870.6C780.7,872.2 784,873 787.8,873C791.6,873 794.9,872.2 797.8,870.6C800.6,869.1 802.8,866.9 804.4,864.1C805.9,861.4 806.7,858.2 806.7,854.7V795.9ZM904.3,826C903.7,823.8 902.8,821.8 901.6,820.1C900.5,818.4 899.1,817 897.4,815.8C895.8,814.6 893.9,813.6 891.8,813C889.7,812.4 887.4,812 884.8,812C880.1,812 875.9,813.2 872.3,815.6C868.7,818 865.9,821.4 863.9,825.9C861.9,830.4 860.9,835.9 860.9,842.4C860.9,848.8 861.9,854.4 863.9,858.9C865.8,863.5 868.6,866.9 872.2,869.3C875.8,871.7 880.1,872.9 885,872.9C889.5,872.9 893.3,872.1 896.4,870.5C899.6,868.9 902,866.6 903.7,863.7C905.4,860.8 906.2,857.4 906.2,853.4L910.2,854H886.2V839.2H925.2V850.9C925.2,859.1 923.5,866.1 920,872C916.5,877.8 911.8,882.4 905.7,885.5C899.7,888.7 892.7,890.3 884.9,890.3C876.2,890.3 868.5,888.3 861.9,884.5C855.3,880.6 850.2,875.1 846.5,868C842.8,860.8 841,852.4 841,842.5C841,835 842,828.3 844.2,822.4C846.4,816.4 849.5,811.4 853.5,807.3C857.5,803.2 862.1,800 867.4,797.9C872.6,795.7 878.3,794.6 884.5,794.6C889.8,794.6 894.7,795.4 899.2,797C903.8,798.5 907.8,800.6 911.3,803.4C914.9,806.2 917.8,809.5 920,813.4C922.2,817.2 923.7,821.4 924.3,826H904.3Z" />
</vector>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="app_name" translatable="false">Thunderbird Debug</string>
</resources>

View file

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="auto">
<application
android:name=".ThunderbirdApp"
android:icon="@drawable/ic_launcher"
android:label="@string/tb_app_name" >
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<!-- We're using on-demand initialization for WorkManager -->
<meta-data
android:name="androidx.work.WorkManagerInitializer"
android:value="androidx.startup"
tools:node="remove" />
</provider>
</application>
</manifest>

View file

@ -0,0 +1,8 @@
package net.thunderbird.android
import com.fsck.k9.CommonApp
import org.koin.core.module.Module
class ThunderbirdApp : CommonApp() {
override fun provideAppModule(): Module = appModule
}

View file

@ -0,0 +1,39 @@
package net.thunderbird.android
import app.k9mail.core.common.oauth.OAuthConfigurationFactory
import app.k9mail.core.ui.compose.theme2.thunderbird.ThunderbirdTheme2
import app.k9mail.feature.launcher.FeatureLauncherExternalContract.FeatureThemeProvider
import com.fsck.k9.AppConfig
import com.fsck.k9.activity.LauncherShortcuts
import com.fsck.k9.activity.MessageCompose
import com.fsck.k9.provider.UnreadWidgetProvider
import com.fsck.k9.widget.list.MessageListWidgetProvider
import net.thunderbird.android.auth.ThunderbirdOAuthConfigurationFactory
import net.thunderbird.android.dev.developmentModuleAdditions
import org.koin.core.qualifier.named
import org.koin.dsl.module
val appModule = module {
single(named("ClientIdAppName")) { BuildConfig.CLIENT_ID_APP_NAME }
single(named("ClientIdAppVersion")) { BuildConfig.VERSION_NAME }
single<AppConfig> { appConfig }
single<OAuthConfigurationFactory> { ThunderbirdOAuthConfigurationFactory() }
single<FeatureThemeProvider> { provideFeatureThemeProvider() }
developmentModuleAdditions()
}
val appConfig = AppConfig(
componentsToDisable = listOf(
MessageCompose::class.java,
LauncherShortcuts::class.java,
UnreadWidgetProvider::class.java,
MessageListWidgetProvider::class.java,
),
)
private fun provideFeatureThemeProvider(): FeatureThemeProvider = FeatureThemeProvider { content ->
ThunderbirdTheme2 {
content()
}
}

View file

@ -0,0 +1,10 @@
package net.thunderbird.android.auth
import app.k9mail.core.common.oauth.OAuthConfiguration
import app.k9mail.core.common.oauth.OAuthConfigurationFactory
class ThunderbirdOAuthConfigurationFactory : OAuthConfigurationFactory {
override fun createConfigurations(): Map<List<String>, OAuthConfiguration> {
return emptyMap()
}
}

View file

@ -0,0 +1,210 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:aapt="http://schemas.android.com/aapt"
android:width="72dp"
android:height="72dp"
android:viewportWidth="1024"
android:viewportHeight="1024">
<path android:pathData="M441,259.7H441.1C467.8,166.5 584,121 702.4,121C784.2,121 857.7,146.9 908,188C878,189.4 848.3,195.3 820,205.5C860.7,220.7 895.6,243.9 921.5,272.7C902,269.3 882.2,267.8 862.4,268.2C911.1,338.8 937.1,422.6 937,508.4C937,742.3 747.4,931.9 513.5,931.9C283.2,931.9 90,739.1 90,508.4C90,472 94.8,434.3 104.2,399.1C106.7,391.6 110.1,384.5 114.7,381.9C120.4,378.7 125.6,388.4 126.5,391.6C132.6,414.7 141,437.3 151.3,459C150.4,410.6 171.1,366.6 199.5,328.5C218.5,303.1 236,279.6 244.1,211.6C244.7,207.1 249,203.8 253.4,205.2C315,225.4 348,328.1 342.9,413.9C376.9,418.8 376.8,383.2 376.8,383.2C365.9,349.8 373.1,287.6 440.9,259.7H441Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="834"
android:endY="817.4"
android:startX="237"
android:startY="260.6"
android:type="linear">
<item
android:color="#FF1B91F3"
android:offset="0" />
<item
android:color="#FF0B68CB"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path
android:fillAlpha="0.9"
android:pathData="M923.1,400.5C933.4,633.5 742,834.3 508.5,834.3C289.9,834.3 110.8,665.3 94.6,450.9C91.7,471 90.2,491.2 90,511.5C91.7,741 284.4,931.9 513.5,931.9C747.4,931.9 937,742.3 937,508.4C937,471.1 932.2,435 923.1,400.5Z"
android:strokeAlpha="0.9">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="235.9"
android:centerY="452.2"
android:gradientRadius="358.1"
android:type="radial">
<item
android:color="#000B4186"
android:offset="0.5" />
<item
android:color="#720B4186"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M503.2,290.6C498.6,282.5 477.5,270.6 468.3,268.5C503.2,156.9 680.7,122.6 789.4,142.4C834.6,150.6 890.9,175.2 908,188C857.7,146.9 784.2,121 702.4,121C584,121 467.8,166.5 441.1,259.7H440.9C373.1,287.6 365.9,349.8 376.8,383.3C387.2,343.3 437,294.3 503.2,290.6Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="524.4"
android:centerY="305.1"
android:gradientRadius="76.6"
android:type="radial">
<item
android:color="#00B39BF6"
android:offset="0" />
<item
android:color="#E5B39BF6"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M626.2,213.5C531.1,232.2 500,238.4 468.2,268.6C503.9,174 595.2,154.8 704,197.9C678.1,203.3 652.2,208.5 626.2,213.5V213.5Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="617.9"
android:endY="164"
android:startX="403.1"
android:startY="403.1"
android:type="linear">
<item
android:color="#FF0F5DB0"
android:offset="0" />
<item
android:color="#000F5DB0"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M113,386.1C87,492.5 107.1,617.6 225.2,722.5C190,684.1 147.1,542.1 241.8,440.8C248.2,433.9 259.1,438.9 259.5,448.3C267.3,659 437.3,787.7 633.4,763.6C572.6,760.2 371.8,689.9 521.2,662C599.3,647.5 721.8,624.7 721.8,514.8C721.8,336.7 584,284.6 500.5,292.3C443.3,297.6 392.5,333.9 376.8,383.2C382.8,402.7 358.8,416.3 342.9,414C348,328.1 315,225.4 253.4,205.2C249,203.8 244.7,207.1 244.1,211.6C236,279.6 218.5,303.1 199.5,328.5C171.1,366.6 150.4,410.6 151.3,459C141,437.3 132.6,414.7 126.5,391.6C125.8,388.9 122,381.6 117.4,381.3C114.9,381.1 113.6,383.5 113,386.1Z">
<aapt:attr name="android:fillColor">
<gradient
android:centerX="353.8"
android:centerY="739.1"
android:gradientRadius="558.7"
android:type="radial">
<item
android:color="#FF094188"
android:offset="0" />
<item
android:color="#000B4186"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M468.7,672.8C583.7,766.2 815,696.2 815,469.2C721.6,610.7 602.7,708.3 468.7,672.8H468.7Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="613.5"
android:endY="756.5"
android:startX="763.5"
android:startY="591"
android:type="linear">
<item
android:color="#00B39BF6"
android:offset="0" />
<item
android:color="#CCB39BF6"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M241.8,440.7C242.8,439.6 244.2,438.7 245.6,438.1C247.1,437.6 248.7,437.4 250.2,437.7C165.5,541 233.8,722.6 280.8,767.2C283.4,774.7 236.2,736 229.8,727C194.1,696.7 142.9,546.6 241.8,440.7Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="248.2"
android:endY="710.5"
android:startX="184"
android:startY="438"
android:type="linear">
<item
android:color="#FFB39BF6"
android:offset="0.1" />
<item
android:color="#00B39BF6"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path android:pathData="M513.5,681.4C628.5,681.4 721.8,605.3 721.8,511.4C721.8,417.6 628.5,341.5 513.5,341.5C415.4,341.5 305.2,405.3 305.2,513.9C305.3,681.7 482.5,778.2 633.6,763.6C622.3,762.3 551.5,758.5 503.6,704.4C499.3,699.5 491.8,691 495.2,685.5C498.6,680 507.9,681.4 513.5,681.4L513.5,681.4Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="513.5"
android:endY="761.9"
android:startX="513.5"
android:startY="403.7"
android:type="linear">
<item
android:color="#FFFFFFFF"
android:offset="0" />
<item
android:color="#FFBEE1FE"
android:offset="0.9" />
<item
android:color="#FF96CEFD"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path
android:fillAlpha="0.7"
android:pathData="M722,511.9C722,605.7 628.8,681.8 513.8,681.8C508.2,681.8 498.9,680.4 495.5,685.9C492.1,691.4 499.6,700 503.9,704.8C548.9,755.7 614.1,762.1 631.2,763.8L633.9,764.1C482.8,778.7 305.5,682.1 305.5,514.4C305.3,486.4 313.1,459 327.9,435.3L490.2,582.7C501.7,593.1 521.1,593.1 532.7,582.7L698,432.5C713.4,456.2 722,483.2 722,511.9Z"
android:strokeAlpha="0.7">
<aapt:attr name="android:fillColor">
<gradient
android:endX="513.8"
android:endY="740.2"
android:startX="513.8"
android:startY="635.5"
android:type="linear">
<item
android:color="#FFBCE0FD"
android:offset="0" />
<item
android:color="#FF88CCFC"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path
android:fillAlpha="0.3"
android:fillColor="#0768BA"
android:pathData="M688,443.5L539.7,605.5C525.1,615.5 501.9,616.7 486.5,607.5L350.5,454.5C355.1,447.3 328.3,428.9 334,422.5L365,448C407.4,486.6 441.8,517.8 490.1,557.8C512,575.9 518.7,575.5 540.2,557.8C595.5,512 646.9,470.6 699.5,425C705.4,431.5 698.8,419.1 703.5,426.4L688,443.5Z" />
<path android:pathData="M698.6,433.4C698.4,433.1 698.2,432.8 698,432.5L532.7,582.7C521.1,593.1 501.7,593.1 490.2,582.7L327.9,435.3C327.8,435.1 327.8,435 327.7,434.8C364.9,375 442.4,341.5 513.5,341.5C594.1,341.5 663.9,378.8 698.6,433.4Z">
<aapt:attr name="android:fillColor">
<gradient
android:endX="513.1"
android:endY="750.5"
android:startX="513.1"
android:startY="378.1"
android:type="linear">
<item
android:color="#FFFFFFFF"
android:offset="0" />
<item
android:color="#FFBEE1FE"
android:offset="0.9" />
<item
android:color="#FF96CEFD"
android:offset="1" />
</gradient>
</aapt:attr>
</path>
<path
android:fillColor="#F2F9FF"
android:pathData="M699.1,434.2L534.5,591.7C519.9,602.1 504.3,602.9 489,593.5L327.5,434.8C332.1,427.4 337.3,420.4 343,413.8L360,429.6C402.4,469.4 436.6,501.5 485,542.7C506.8,561.3 513.5,560.9 534.9,542.7C590.2,495.5 630.6,459.8 683.2,412.9C689,419.6 694.3,426.7 699.1,434.2L699.1,434.2Z" />
<path
android:fillColor="#ffffff"
android:pathData="M542.7,256.5C565,249.5 563,227.4 563,227.4C563,227.4 551.9,214.3 529.8,221.5C509.1,228.4 505.9,243.1 505.9,243.1C505.9,243.1 517.2,264.5 542.7,256.5Z" />
</vector>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<drawable name="ic_launcher">@drawable/ic_app_logo</drawable>
</resources>

View file

@ -0,0 +1,4 @@
<?xml version="1.0" encoding="UTF-8"?>
<resources xmlns:xliff="urn:oasis:names:tc:xliff:document:1.2">
<string name="tb_app_name" translatable="false">Thunderbird</string>
</resources>

View file

@ -0,0 +1,11 @@
package net.thunderbird.android.dev
import com.fsck.k9.backend.BackendFactory
import org.koin.core.module.Module
import org.koin.core.qualifier.named
fun Module.developmentModuleAdditions() {
single<Map<String, BackendFactory>>(named("developmentBackends")) {
emptyMap()
}
}

View file

@ -0,0 +1,65 @@
package net.thunderbird.android
import android.view.ContextThemeWrapper
import androidx.lifecycle.LifecycleOwner
import androidx.work.WorkerParameters
import app.k9mail.feature.account.server.validation.domain.ServerValidationDomainContract
import app.k9mail.feature.account.server.validation.ui.ServerValidationContract
import com.fsck.k9.account.AccountRemoverWorker
import com.fsck.k9.job.MailSyncWorker
import com.fsck.k9.mail.oauth.AuthStateStorage
import com.fsck.k9.ui.R
import com.fsck.k9.ui.changelog.ChangeLogMode
import com.fsck.k9.ui.changelog.ChangelogViewModel
import com.fsck.k9.ui.endtoend.AutocryptKeyTransferActivity
import com.fsck.k9.ui.endtoend.AutocryptKeyTransferPresenter
import com.fsck.k9.ui.folders.FolderIconProvider
import com.fsck.k9.ui.folders.FolderNameFormatter
import com.fsck.k9.ui.helper.SizeFormatter
import org.junit.Test
import org.junit.runner.RunWith
import org.koin.core.annotation.KoinInternalApi
import org.koin.core.logger.PrintLogger
import org.koin.core.parameter.parametersOf
import org.koin.java.KoinJavaComponent
import org.koin.test.AutoCloseKoinTest
import org.koin.test.check.checkModules
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.openintents.openpgp.OpenPgpApiManager
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
@RunWith(RobolectricTestRunner::class)
class DependencyInjectionTest : AutoCloseKoinTest() {
private val lifecycleOwner = mock<LifecycleOwner> {
on { lifecycle } doReturn mock()
}
private val autocryptTransferView = mock<AutocryptKeyTransferActivity>()
private val authStateStorage = mock<AuthStateStorage>()
@KoinInternalApi
@Test
fun testDependencyTree() {
KoinJavaComponent.getKoin().setupLogger(PrintLogger())
getKoin().checkModules {
withParameter<OpenPgpApiManager> { lifecycleOwner }
withParameters<AutocryptKeyTransferPresenter> { parametersOf(lifecycleOwner, autocryptTransferView) }
withParameter<FolderNameFormatter> { RuntimeEnvironment.getApplication() }
withParameter<SizeFormatter> { RuntimeEnvironment.getApplication() }
withParameter<ChangelogViewModel> { ChangeLogMode.CHANGE_LOG }
withParameter<MailSyncWorker> { mock<WorkerParameters>() }
withParameter<FolderIconProvider> {
ContextThemeWrapper(RuntimeEnvironment.getApplication(), R.style.Theme_K9_DayNight).theme
}
withParameters(clazz = Class.forName("com.fsck.k9.view.K9WebViewClient").kotlin) {
parametersOf(null, null)
}
withParameter<ServerValidationContract.IncomingViewModel> { authStateStorage }
withParameter<ServerValidationContract.OutgoingViewModel> { authStateStorage }
withParameter<ServerValidationDomainContract.UseCase.ValidateServerSettings> { authStateStorage }
withParameter<AccountRemoverWorker> { mock<WorkerParameters>() }
}
}
}

View file

@ -0,0 +1,150 @@
package net.thunderbird.android.unread
import android.content.Context
import assertk.assertThat
import assertk.assertions.isEqualTo
import assertk.assertions.isNull
import com.fsck.k9.Account
import com.fsck.k9.Preferences
import com.fsck.k9.controller.MessageCounts
import com.fsck.k9.controller.MessageCountsProvider
import com.fsck.k9.mailstore.Folder
import com.fsck.k9.mailstore.FolderRepository
import com.fsck.k9.mailstore.FolderType
import com.fsck.k9.search.SearchAccount
import com.fsck.k9.ui.folders.FolderNameFormatter
import com.fsck.k9.ui.messagelist.DefaultFolderProvider
import com.fsck.k9.widget.unread.UnreadWidgetConfiguration
import com.fsck.k9.widget.unread.UnreadWidgetDataProvider
import org.junit.Test
import org.junit.runner.RunWith
import org.koin.test.AutoCloseKoinTest
import org.mockito.kotlin.doReturn
import org.mockito.kotlin.mock
import org.robolectric.RobolectricTestRunner
import org.robolectric.RuntimeEnvironment
@RunWith(RobolectricTestRunner::class)
class UnreadWidgetDataProviderTest : AutoCloseKoinTest() {
private val context: Context = RuntimeEnvironment.getApplication()
private val account = createAccount()
private val preferences = createPreferences()
private val messageCountsProvider = createMessageCountsProvider()
private val defaultFolderStrategy = createDefaultFolderStrategy()
private val folderRepository = createFolderRepository()
private val folderNameFormatter = createFolderNameFormatter()
private val provider = UnreadWidgetDataProvider(
context,
preferences,
messageCountsProvider,
defaultFolderStrategy,
folderRepository,
folderNameFormatter,
)
@Test
fun unifiedInbox() {
val configuration = UnreadWidgetConfiguration(
appWidgetId = 1,
accountUuid = SearchAccount.UNIFIED_INBOX,
folderId = null,
)
val widgetData = provider.loadUnreadWidgetData(configuration)
with(widgetData!!) {
assertThat(title).isEqualTo("Unified Inbox")
assertThat(unreadCount).isEqualTo(SEARCH_ACCOUNT_UNREAD_COUNT)
}
}
@Test
fun regularAccount() {
val configuration = UnreadWidgetConfiguration(
appWidgetId = 3,
accountUuid = ACCOUNT_UUID,
folderId = null,
)
val widgetData = provider.loadUnreadWidgetData(configuration)
with(widgetData!!) {
assertThat(title).isEqualTo(ACCOUNT_NAME)
assertThat(unreadCount).isEqualTo(ACCOUNT_UNREAD_COUNT)
}
}
@Test
fun folder() {
val configuration = UnreadWidgetConfiguration(appWidgetId = 4, accountUuid = ACCOUNT_UUID, folderId = FOLDER_ID)
val widgetData = provider.loadUnreadWidgetData(configuration)
with(widgetData!!) {
assertThat(title).isEqualTo("$ACCOUNT_NAME - $LOCALIZED_FOLDER_NAME")
assertThat(unreadCount).isEqualTo(FOLDER_UNREAD_COUNT)
}
}
@Test
fun nonExistentAccount_shouldReturnNull() {
val configuration = UnreadWidgetConfiguration(appWidgetId = 3, accountUuid = "invalid", folderId = null)
val widgetData = provider.loadUnreadWidgetData(configuration)
assertThat(widgetData).isNull()
}
private fun createAccount(): Account = mock {
on { uuid } doReturn ACCOUNT_UUID
on { displayName } doReturn ACCOUNT_NAME
}
private fun createPreferences(): Preferences = mock {
on { getAccount(ACCOUNT_UUID) } doReturn account
}
private fun createMessageCountsProvider() = object : MessageCountsProvider {
override fun getMessageCounts(account: Account): MessageCounts {
return MessageCounts(unread = ACCOUNT_UNREAD_COUNT, starred = 0)
}
override fun getMessageCounts(searchAccount: SearchAccount): MessageCounts {
return MessageCounts(unread = SEARCH_ACCOUNT_UNREAD_COUNT, starred = 0)
}
override fun getUnreadMessageCount(account: Account, folderId: Long): Int {
return FOLDER_UNREAD_COUNT
}
}
private fun createDefaultFolderStrategy(): DefaultFolderProvider = mock {
on { getDefaultFolder(account) } doReturn FOLDER_ID
}
private fun createFolderRepository(): FolderRepository {
return mock {
on { getFolder(account, FOLDER_ID) } doReturn FOLDER
}
}
private fun createFolderNameFormatter(): FolderNameFormatter = mock {
on { displayName(FOLDER) } doReturn LOCALIZED_FOLDER_NAME
}
companion object {
const val ACCOUNT_UUID = "00000000-0000-0000-0000-000000000000"
const val ACCOUNT_NAME = "Test account"
const val FOLDER_ID = 23L
const val SEARCH_ACCOUNT_UNREAD_COUNT = 1
const val ACCOUNT_UNREAD_COUNT = 2
const val FOLDER_UNREAD_COUNT = 3
const val LOCALIZED_FOLDER_NAME = "Posteingang"
val FOLDER = Folder(
id = FOLDER_ID,
name = "INBOX",
type = FolderType.INBOX,
isLocalOnly = false,
)
}
}

View file

@ -31,7 +31,6 @@
android:usesCleartextTraffic="true"
android:networkSecurityConfig="@xml/network_security_config"
android:icon="@drawable/ic_launcher"
android:label="@string/app_name"
android:theme="@style/Theme.K9.Startup"
android:resizeableActivity="true"
android:allowBackup="false"

View file

@ -22,6 +22,7 @@ rootProject.name = "k-9"
include(
":app-k9mail",
":app-thunderbird",
":app-ui-catalog",
)