Initial commit
Some checks failed
Main Deploy Workflow / deploy_web (push) Has been cancelled
Main Deploy Workflow / deploy_playstore_internal (push) Has been cancelled
Close stale issues and PRs / stale (push) Has been cancelled

This commit is contained in:
2026-09-11 15:59:56 -03:00
commit 0037b0b9cf
651 changed files with 199705 additions and 0 deletions

13
android/.gitignore vendored Normal file
View File

@@ -0,0 +1,13 @@
gradle-wrapper.jar
/.gradle
/captures/
/gradlew
/gradlew.bat
/local.properties
GeneratedPluginRegistrant.java
# Remember to never publicly share your keystore.
# See https://flutter.dev/docs/deployment/android#reference-the-keystore-from-the-app
key.properties
**/*.keystore
**/*.jks

4
android/Gemfile Normal file
View File

@@ -0,0 +1,4 @@
source "https://rubygems.org"
gem "fastlane"
gem "multi_json"

View File

@@ -0,0 +1,98 @@
import java.util.Properties
import java.io.FileInputStream
plugins {
id("com.android.application")
// The Flutter Gradle Plugin must be applied after the Android and Kotlin Gradle plugins.
id("dev.flutter.flutter-gradle-plugin")
}
if (file("google-services.json").exists()) {
apply(plugin = "com.google.gms.google-services")
}
dependencies {
coreLibraryDesugaring("com.android.tools:desugar_jdk_libs:2.1.4") // For flutter_local_notifications // Workaround for: https://github.com/MaikuB/flutter_local_notifications/issues/2286
implementation("androidx.core:core-ktx:1.17.0") // For Android Auto
}
// Workaround for https://pub.dev/packages/unifiedpush#the-build-fails-because-of-duplicate-classes
configurations.all {
// Use the latest version published: https://central.sonatype.com/artifact/com.google.crypto.tink/tink-android
val tink = "com.google.crypto.tink:tink-android:1.23.0"
// You can also use the library declaration catalog
// val tink = libs.google.tink
resolutionStrategy {
force(tink)
dependencySubstitution {
substitute(module("com.google.crypto.tink:tink")).using(module(tink))
}
}
}
android {
namespace = "chat.fluffy.tatuchat"
// Workaround for https://github.com/juliansteenbakker/flutter_secure_storage/issues/1224
compileSdk = 37 //flutter.compileSdkVersion
ndkVersion = flutter.ndkVersion
compileOptions {
sourceCompatibility = JavaVersion.VERSION_11
targetCompatibility = JavaVersion.VERSION_11
isCoreLibraryDesugaringEnabled = true
}
signingConfigs {
create("release") {
keyAlias = "dummyAlias"
keyPassword = "dummyPassword"
storeFile = file("dummy.keystore")
storePassword = "dummyStorePassword"
}
}
val keystoreProperties = Properties()
val keystorePropertiesFile = rootProject.file("key.properties")
if (keystorePropertiesFile.exists()) {
keystoreProperties.load(FileInputStream(keystorePropertiesFile))
signingConfigs.getByName("release").apply {
keyAlias = keystoreProperties["keyAlias"] as String
keyPassword = keystoreProperties["keyPassword"] as String
storeFile = keystoreProperties["storeFile"]?.let { file(it) }
storePassword = keystoreProperties["storePassword"] as String
}
}
defaultConfig {
applicationId = "chat.fluffy.tatuchat"
minSdk = flutter.minSdkVersion
targetSdk = flutter.targetSdkVersion
versionCode = flutter.versionCode
versionName = flutter.versionName
ndk { // Workaround for https://github.com/flutter/flutter/issues/162153#issuecomment-2612443642
abiFilters += listOf("armeabi-v7a", "arm64-v8a", "x86_64", "x86")
}
}
buildTypes {
release {
signingConfig = signingConfigs.getByName("release")
isMinifyEnabled = true
isShrinkResources = true
proguardFiles(getDefaultProguardFile("proguard-android.txt"), "proguard-rules.pro")
}
}
}
kotlin {
compilerOptions {
jvmTarget = org.jetbrains.kotlin.gradle.dsl.JvmTarget.JVM_11
}
}
flutter {
source = "../.."
}

1
android/app/proguard-rules.pro vendored Normal file
View File

@@ -0,0 +1 @@
-keep class com.hiennv.flutter_callkit_incoming.** { *; }

View File

@@ -0,0 +1,147 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools"
android:installLocation="auto">
<!-- io.flutter.app.FlutterApplication is an android.app.Application that
calls FlutterMain.startInitialization(this); in its onCreate method.
In most cases you can leave this as-is, but you if you want to provide
additional functionality it is fine to subclass or reimplement
FlutterApplication and put your custom class here. -->
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="android.permission.VIBRATE" />
<uses-permission android:name="android.permission.RECORD_AUDIO" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.ACCESS_FINE_LOCATION" />
<uses-permission android:name="android.permission.ACCESS_COARSE_LOCATION" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.BLUETOOTH" />
<uses-permission android:name="android.permission.MODIFY_AUDIO_SETTINGS" />
<uses-permission android:name="android.permission.WAKE_LOCK" />
<uses-permission android:name="android.permission.USE_BIOMETRIC"/>
<uses-permission android:name="android.permission.FOREGROUND_SERVICE" />
<uses-permission android:name="android.permission.FOREGROUND_SERVICE_SHORT_SERVICE" />
<!-- To make app compatible with tablets -->
<uses-feature android:name="android.hardware.camera" android:required="false"/>
<uses-feature android:name="android.hardware.microphone" android:required="false" />
<uses-sdk
tools:overrideLibrary="io.wazo.callkeep, net.touchcapture.qr.flutterqr, com.cloudwebrtc.webrtc, org.webrtc, com.it_nomads.fluttersecurestorage, com.pichillilorenzo.flutter_inappwebview, com.example.video_compress, com.otaliastudios.transcoder, com.otaliastudios.opengl, com.kineapps.flutter_file_dialog, com.llfbandit.record, com.pravera.flutter_foreground_task"/>
<application
android:label="TatuChat"
android:icon="@mipmap/ic_launcher"
android:requestLegacyExternalStorage="true"
android:allowBackup="false"
android:fullBackupContent="false"
android:localeConfig="@xml/locale_config"
>
<activity
android:name=".MainActivity"
android:launchMode="singleTask"
android:theme="@style/LaunchTheme"
android:configChanges="orientation|keyboardHidden|keyboard|screenSize|smallestScreenSize|locale|layoutDirection|fontScale|screenLayout|density|uiMode"
android:hardwareAccelerated="true"
android:showOnLockScreen="false"
android:turnScreenOn="true"
android:windowSoftInputMode="adjustResize"
android:exported="true">
<intent-filter>
<action android:name="android.intent.action.MAIN"/>
<category android:name="android.intent.category.LAUNCHER"/>
</intent-filter>
<!-- App can open on notification action -->
<intent-filter>
<action android:name="FLUTTER_NOTIFICATION_CLICK" />
<category android:name="android.intent.category.DEFAULT" />
</intent-filter>
<!-- App can open https://matrix.to urls -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data
android:scheme="https"
android:host="matrix.to"/>
</intent-filter>
<!-- App can open matrix: uris -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="matrix" />
</intent-filter>
<!-- App can open im.tatuchat:// uris -->
<intent-filter>
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="im.tatuchat" android:host="chat" />
</intent-filter>
<!-- App can receive shared text -->
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="text/*" />
</intent-filter>
<!-- App can receive shared any type of files -->
<intent-filter>
<action android:name="android.intent.action.SEND" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
<intent-filter>
<action android:name="android.intent.action.SEND_MULTIPLE" />
<category android:name="android.intent.category.DEFAULT" />
<data android:mimeType="*/*" />
</intent-filter>
</activity>
<activity
android:name="com.linusu.flutter_web_auth_2.CallbackActivity"
android:exported="true">
<intent-filter android:label="flutter_web_auth">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="im.tatuchat.auth" android:path="/login"/>
</intent-filter>
</activity>
<service android:name=".FcmPushService"
android:exported="false">
<intent-filter>
<action android:name="com.google.firebase.MESSAGING_EVENT"/>
</intent-filter>
</service>
<service android:name="com.pravera.flutter_foreground_task.service.ForegroundService"
android:foregroundServiceType="camera|microphone|mediaProjection|shortService"
android:exported="false">
</service>
<!-- From flutter_local_notifications package for notification actions -->
<receiver android:exported="false" android:name="com.dexterous.flutterlocalnotifications.ActionBroadcastReceiver" />
<!-- To make notifications available in Android Auto -->
<meta-data
android:name="com.google.android.gms.car.application"
android:resource="@xml/automotive_app_desc"/>
<!-- Don't delete the meta-data below.
This is used by the Flutter tool to generate GeneratedPluginRegistrant.java -->
<meta-data
android:name="flutterEmbedding"
android:value="2" />
<!-- Enables configuration via MDM -->
<meta-data android:name="android.content.APP_RESTRICTIONS"
android:resource="@xml/app_restrictions" />
</application>
</manifest>

View File

@@ -0,0 +1,28 @@
/*package chat.fluffy.fluffychat
import com.famedly.fcm_shared_isolate.FcmSharedIsolateService
import io.flutter.embedding.engine.FlutterEngine
import io.flutter.embedding.engine.dart.DartExecutor.DartEntrypoint
import android.content.Context
class FcmPushService : FcmSharedIsolateService() {
override fun getEngine(): FlutterEngine {
return provideEngine(getApplicationContext())
}
companion object {
fun provideEngine(context: Context): FlutterEngine {
var engine = MainActivity.engine
if (engine == null) {
engine = MainActivity.provideEngine(context)
engine.getLocalizationPlugin().sendLocalesToFlutter(
context.getResources().getConfiguration())
engine.getDartExecutor().executeDartEntrypoint(
DartEntrypoint.createDefault())
}
return engine
}
}
}
*/

View File

@@ -0,0 +1,31 @@
package chat.fluffy.fluffychat
import io.flutter.embedding.android.FlutterFragmentActivity
import io.flutter.embedding.engine.FlutterEngine
import android.content.Context
class MainActivity : FlutterFragmentActivity() {
override fun attachBaseContext(base: Context) {
super.attachBaseContext(base)
}
override fun provideFlutterEngine(context: Context): FlutterEngine? {
return provideEngine(this)
}
override fun configureFlutterEngine(flutterEngine: FlutterEngine) {
// do nothing, because the engine was been configured in provideEngine
}
companion object {
var engine: FlutterEngine? = null
fun provideEngine(context: Context): FlutterEngine {
val eng = engine ?: FlutterEngine(context, emptyArray(), true, false)
engine = eng
return eng
}
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 598 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 882 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 396 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 566 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 5.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 B

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
</item>
<item>
<bitmap android:gravity="center" android:src="@drawable/splash"/>
</item>
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 B

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
</item>
<item>
<bitmap android:gravity="center" android:src="@drawable/splash"/>
</item>
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
</item>
<item>
<bitmap android:gravity="center" android:src="@drawable/splash"/>
</item>
</layer-list>

Binary file not shown.

After

Width:  |  Height:  |  Size: 814 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 9.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 10 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 14 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 16 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.9 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 20 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 68 B

View File

@@ -0,0 +1,29 @@
<vector xmlns:android="http://schemas.android.com/apk/res/android"
android:width="108dp"
android:height="108dp"
android:viewportWidth="108"
android:viewportHeight="108">
<group android:scaleX="0.33822063"
android:scaleY="0.33822063"
android:translateX="30.24"
android:translateY="31.24">
<path
android:pathData="M130.9,74.3c1.5,-0.3 2.8,-1 3.8,-2 4,-5.3 0.8,-11.8 -4.5,-12.6 -0.8,0 -1.5,-0.8 -1.5,-1.5v-0.5c0.8,-0.8 1.5,-1.8 2.5,-3.3 8.1,-10.8 11.8,-50.6 3.8,-53.7 -9.8,-3.3 -29.7,6.3 -38.3,17.4 -0.5,-0.3 -1,-1 -1,-1.8a7,7 0,0 0,-3.5 -6.8,7.8 7.8,0 0,0 -10.6,3.3c-0.5,0.8 -1.3,1.3 -2,1 -0.8,0 -1.5,-0.8 -1.5,-1.5 -0.5,-2.5 -2,-4.5 -4.3,-5.5 -4.8,-2 -9.8,0.8 -10.6,5.3 -0.3,0.8 -0.8,1.5 -1.5,1.5 -0.8,0.3 -1.5,-0.3 -2,-1a8,8 0,0 0,-6.5 -3.8,8 8,0 0,0 -7.8,7.3v0.6c0,0.8 -0.5,1.5 -1,1.8h-0.3c-8.3,-10.8 -28.5,-20.7 -38.5,-17.4 -8.1,2.8 -4.3,42.6 4,53.4 1.5,2 2.8,3.5 3.8,4.5 -0.3,0.8 -1,1.5 -1.8,1.5 -1.3,0 -2.5,0.5 -3.5,1.3a7.7,7.7 0,0 0,3 13.4c0.8,0.3 1.5,1 1.5,1.8s-0.5,1.8 -1.3,2c-1,0.5 -2,1 -2.8,2 -4,5.8 0,12.3 5.5,12.3a2,2 0,0 1,1.8 1.3c0.3,0.8 0.3,1.5 -0.5,2a6.5,6.5 0,0 0,-2 5.5c0.3,2.8 2,5.3 4.8,6.5 1.5,0.8 3,0.8 4.5,0.5 0.8,-0.3 1.5,0 2,0.8 0.5,0.5 0.5,1.5 0.3,2 -0.8,1.5 -1,3.3 -0.5,5a7.7,7.7 0,0 0,5.5 5.5c2.5,0.5 4.3,-0.3 5.5,-0.8 0.5,-0.3 -3.3,9.1 -6,15.4 -0.8,2 1.3,4.3 3.5,3.3 8.3,-3.8 22.2,-10.3 22.2,-9.8 0.5,5.3 6.5,9.1 12.3,5.3 1.3,-0.8 2,-2.3 2.3,-3.5 0.3,-0.8 1,-1.5 2,-1.5s1.8,0.5 2,1.5c0.3,1.3 0.8,2.3 1.8,3 5.8,4.5 12.3,0.8 12.8,-4.8a2,2 0,0 1,1.3 -1.8c0.8,-0.3 1.5,0 2,0.5a7.6,7.6 0,0 0,5.3 2.5c2.5,0 5,-1.3 6.5,-3.8 1,-1.5 1.3,-3 1,-5 0,-0.8 0.3,-1.5 0.8,-2s1.5,-0.5 2,0c1.5,0.8 3.3,1.3 5,0.8 2.8,-0.5 5,-2.8 5.8,-5.3 0.5,-1.8 0.3,-3.5 -0.5,-5.3 -0.3,-0.8 -0.3,-1.5 0.3,-2s1.3,-0.8 2,-0.8c1.8,0.3 3.3,0.3 4.8,-0.5 2.3,-1 3.8,-3 4.3,-5.5a7,7 0,0 0,-2 -6.5c-0.5,-0.5 -0.8,-1.3 -0.5,-2 0.3,-0.7 1,-1.3 1.8,-1.3 1.8,0 3.8,-0.5 5,-2a7.6,7.6 0,0 0,-2.5 -12.6c-0.8,-0.3 -1.3,-1 -1.3,-2 0,-0.9 0.7,-1.6 1.5,-1.6z"
android:fillColor="#4d3f92"/>
<path
android:pathData="M110.7,21.4a7,7 0,0 1,0 4.5c-0.3,0.8 0,1.5 0.5,2s1.3,0.8 2,0.5c1,-0.5 2,-0.5 3,-0.5a7,7 0,0 1,5.8 3c1,1.3 1.8,3 1.5,4.8a7,7 0,0 1,-1.3 4c-0.5,0.5 -0.5,1.5 0,2 0.3,0.3 0.5,0.8 1,0.8 1,-0.3 2,-1 2.8,-2 4.5,-6.3 5.3,-26.2 0.8,-27.7s-12.3,1.5 -17.9,6c1.1,0.5 1.6,1.3 1.8,2.6z"
android:fillColor="#fff"/>
<path
android:pathData="M18.3,42.8l0.8,-0.8c0.5,-0.8 0.3,-1.5 0,-2a7.6,7.6 0,0 1,-1.3 -5.8c0.5,-2.8 2.8,-5 5.5,-5.8 1.5,-0.5 3,-0.3 4.5,0.3 0.8,0.3 1.5,0 2,-0.5s0.8,-1.3 0.5,-2a7,7 0,0 1,0 -4.5c0.3,-1 0.8,-2 1.5,-2.8 -5.5,-4.5 -13.9,-7.8 -18.4,-6.3 -4.5,1.5 -3.7,21.4 0.9,27.7 1,1.5 2.2,2.2 4,2.5z"
android:fillColor="#fff"/>
<path
android:pathData="M40.2,73.8m-9.3,0a9.3,9.3 0,1 1,18.6 0a9.3,9.3 0,1 1,-18.6 0"
android:fillColor="#fff"/>
<path
android:pathData="M80,73.8a9.3,9.3 0,1 1,-18.6 0c0,-5 18.6,-5.3 18.6,0z"
android:fillColor="#fff"/>
<path
android:pathData="M100.9,73.8m-9.3,0a9.3,9.3 0,1 1,18.6 0a9.3,9.3 0,1 1,-18.6 0"
android:fillColor="#fff"/>
</group>
</vector>

File diff suppressed because one or more lines are too long

View File

@@ -0,0 +1,9 @@
<?xml version="1.0" encoding="utf-8"?>
<layer-list xmlns:android="http://schemas.android.com/apk/res/android">
<item>
<bitmap android:gravity="fill" android:src="@drawable/background"/>
</item>
<item>
<bitmap android:gravity="center" android:src="@drawable/splash"/>
</item>
</layer-list>

View File

@@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<adaptive-icon xmlns:android="http://schemas.android.com/apk/res/android">
<background android:drawable="@drawable/ic_launcher_background"/>
<foreground>
<inset
android:drawable="@drawable/ic_launcher_foreground"
android:inset="16%" />
</foreground>
<monochrome>
<inset
android:drawable="@drawable/ic_launcher_monochrome"
android:inset="16%" />
</monochrome>
</adaptive-icon>

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.1 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.8 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 3.7 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 6.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 7.5 KiB

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<!-- Theme applied to the Android Window while the process is starting when the OS's Dark Mode setting is on -->
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
<item name="android:windowFullscreen">false</item>
</style>
<!-- Theme applied to the Android Window as soon as the process has started.
This theme determines the color of the Android Window while your
Flutter UI initializes, as well as behind your Flutter UI while its
running.
This Theme is only used starting with V2 of Flutter's Android embedding. -->
<style name="NormalTheme" parent="@android:style/Theme.Black.NoTitleBar">
<item name="android:windowBackground">?android:colorBackground</item>
</style>
</resources>

View File

@@ -0,0 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<color name="ic_launcher_background">#FFFFFF</color>
</resources>

View File

@@ -0,0 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<resources>
<style name="LaunchTheme" parent="@android:style/Theme.Black.NoTitleBar">
<!-- Show a splash screen on the activity. Automatically removed when
Flutter draws its first frame -->
<item name="android:windowBackground">@drawable/launch_background</item>
</style>
</resources>

View File

@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<restrictions xmlns:android="http://schemas.android.com/apk/res/android">
<restriction
android:key="defaultHomeserver"
android:title="Default Homeserver"
android:restrictionType="string" />
<restriction
android:key="presetHomeserver"
android:title="Preset Homeserver"
android:restrictionType="string" />
<restriction
android:key="welcomeText"
android:title="Welcome text"
android:restrictionType="string" />
</restrictions>

View File

@@ -0,0 +1,3 @@
<automotiveApp>
<uses name="notification" />
</automotiveApp>

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="utf-8"?>
<locale-config xmlns:android="http://schemas.android.com/apk/res/android">
<locale android:name="ar"/>
<locale android:name="az"/>
<locale android:name="be"/>
<locale android:name="bn"/>
<locale android:name="bo"/>
<locale android:name="ca"/>
<locale android:name="cs"/>
<locale android:name="da"/>
<locale android:name="de"/>
<locale android:name="el"/>
<locale android:name="en"/>
<locale android:name="eo"/>
<locale android:name="es"/>
<locale android:name="et"/>
<locale android:name="eu"/>
<locale android:name="fa"/>
<locale android:name="fi"/>
<locale android:name="fil"/>
<locale android:name="fr"/>
<locale android:name="ga"/>
<locale android:name="gl"/>
<locale android:name="he"/>
<locale android:name="hi"/>
<locale android:name="hr"/>
<locale android:name="hu"/>
<locale android:name="ia"/>
<locale android:name="id"/>
<locale android:name="ie"/>
<locale android:name="it"/>
<locale android:name="ja"/>
<locale android:name="ka"/>
<locale android:name="kab"/>
<locale android:name="ko"/>
<locale android:name="la"/>
<locale android:name="lt"/>
<locale android:name="lv"/>
<locale android:name="nb"/>
<locale android:name="nl"/>
<locale android:name="pl"/>
<locale android:name="pt"/>
<locale android:name="pt"/>
<locale android:name="pt"/>
<locale android:name="ro"/>
<locale android:name="ru"/>
<locale android:name="sk"/>
<locale android:name="sl"/>
<locale android:name="sq"/>
<locale android:name="sr"/>
<locale android:name="sv"/>
<locale android:name="ta"/>
<locale android:name="te"/>
<locale android:name="th"/>
<locale android:name="tr"/>
<locale android:name="uk"/>
<locale android:name="uz"/>
<locale android:name="vi"/>
<locale android:name="yue"/>
<locale android:name="zh"/>
<locale android:name="zh"/>
</locale-config>

21
android/build.gradle.kts Normal file
View File

@@ -0,0 +1,21 @@
allprojects {
repositories {
google()
mavenCentral()
}
}
val newBuildDir: Directory = rootProject.layout.buildDirectory.dir("../../build").get()
rootProject.layout.buildDirectory.value(newBuildDir)
subprojects {
val newSubprojectBuildDir: Directory = newBuildDir.dir(project.name)
project.layout.buildDirectory.value(newSubprojectBuildDir)
}
subprojects {
project.evaluationDependsOn(":app")
}
tasks.register<Delete>("clean") {
delete(rootProject.layout.buildDirectory)
}

2
android/fastlane/Appfile Normal file
View File

@@ -0,0 +1,2 @@
json_key_file("keys.json") # Path to the json secret file - Follow https://docs.fastlane.tools/actions/supply/#setup to get one
package_name("chat.fluffy.fluffychat") # e.g. com.krausefx.app

80
android/fastlane/Fastfile Normal file
View File

@@ -0,0 +1,80 @@
# This file contains the fastlane.tools configuration
# You can find the documentation at https://docs.fastlane.tools
#
# For a list of all available actions, check out
#
# https://docs.fastlane.tools/actions
#
# For a list of all available plugins, check out
#
# https://docs.fastlane.tools/plugins/available-plugins
#
# Workaround for https://github.com/fastlane/fastlane/issues/21507#issuecomment-1723116829
ENV['SUPPLY_UPLOAD_MAX_RETRIES']='5'
# Uncomment the line if you want fastlane to automatically update itself
update_fastlane
default_platform(:android)
platform :android do
lane :set_build_code_internal do
versions = google_play_track_version_codes(
track: "internal",
json_key: "./keys.json"
)
last_version = versions[0].to_i
Dir.chdir("../..") do
re = /version:\s([0-9]*\.[0-9]*\.[0-9]*)\+[0-9]*/i
config = File.read("./pubspec.yaml")
version_name = config.match(re).captures
subst = "version: #{version_name[0]}+#{last_version+2}"
result = config.gsub(re, subst)
File.open("./pubspec.yaml", 'w') { |file| file.write(result) }
end
end
lane :deploy_internal_test do
versions = google_play_track_version_codes(
track: "internal",
json_key: "./keys.json"
)
last_version = versions[0].to_i
upload_to_play_store(
track: 'internal',
aab: '../build/app/outputs/bundle/release/app-release.aab',
version_code: "#{last_version+1}",
skip_upload_metadata: true,
skip_upload_images: true,
skip_upload_screenshots: true,
)
end
lane :deploy_candidate do
upload_to_play_store(
track: 'internal',
track_promote_to: "beta",
deactivate_on_promote: false,
skip_upload_metadata: true,
skip_upload_images: true,
skip_upload_screenshots: true,
skip_upload_changelogs: true,
)
end
lane :deploy_release do
upload_to_play_store(
track: 'internal',
track_promote_to: "production",
deactivate_on_promote: false,
skip_upload_metadata: true,
skip_upload_images: true,
skip_upload_screenshots: true,
skip_upload_changelogs: true,
)
end
end

View File

@@ -0,0 +1,56 @@
fastlane documentation
----
# Installation
Make sure you have the latest version of the Xcode command line tools installed:
```sh
xcode-select --install
```
For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
# Available Actions
## Android
### android set_build_code_internal
```sh
[bundle exec] fastlane android set_build_code_internal
```
### android deploy_internal_test
```sh
[bundle exec] fastlane android deploy_internal_test
```
### android deploy_candidate
```sh
[bundle exec] fastlane android deploy_candidate
```
### android deploy_release
```sh
[bundle exec] fastlane android deploy_release
```
----
This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).

View File

@@ -0,0 +1,2 @@
FluffyChat 2.9.0 updates underlying libraries, fixed a lot of bugs and improves the UX.
The app now uses http3 and the system's proxy by default.

View File

@@ -0,0 +1,31 @@
### Messaging how it should be
Whether for your friends, your company or local community, TatuChat supports a variety of features to cover all your daily needs.
#### Easy to use
Simply install, log in and start chatting. The intuitive user interface makes secure communication as easy as possible.
#### Secure
With olm/megolm end-to-end encryption, encrypted message backups and an automated key trust system, TatuChat is among the most secure messengers available.
#### Decentral
Based on the open Matrix protocol we build a decentralized messaging network together, which no entity can control. Host your own chat server while remaining in contact with everyone.
### Feature rich and reliable
From public chats with tens of thousands of participants and polls to custom stickers, spaces, rich moderation tools, and multi-device support, TatuChat delivers a comprehensive communication suite.
#### Secure video calls
Direct calls and video conferences, fully secured with Matrix RTC-compatible encryption.
#### Not another walled garden
We do not build another walled garden! TatuChat is fully compatible with any other Matrix client like Element, Nheko, Cinny or NeoChat. Learn more at matrix.org.
#### Made by volunteers
TatuChat is a non-profit project based on open standards and driven entirely by volunteers. Infrastructure is funded by donations, and participation is open to everyone.

Binary file not shown.

After

Width:  |  Height:  |  Size: 86 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 435 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 952 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 248 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 426 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 951 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 168 KiB

View File

@@ -0,0 +1 @@
The open-source, non-profit European alternative to big tech’s messaging and video-call monopoly. End-to-end encrypted, decentralized, and easy to use for everyone.

View File

@@ -0,0 +1 @@
TatuChat Matrix Messenger

View File

@@ -0,0 +1,23 @@
<?xml version="1.0" encoding="UTF-8"?>
<testsuites>
<testsuite name="fastlane.lanes">
<testcase classname="fastlane.lanes" name="0: update_fastlane" time="1.455419">
</testcase>
<testcase classname="fastlane.lanes" name="1: default_platform" time="0.000127">
</testcase>
<testcase classname="fastlane.lanes" name="2: google_play_track_version_codes" time="2.638619">
</testcase>
</testsuite>
</testsuites>

View File

@@ -0,0 +1,8 @@
org.gradle.jvmargs=-Xmx4608m
android.useAndroidX=true
android.enableJetifier=true
kotlin.jvm.target.validation.mode=IGNORE
# This builtInKotlin flag was added automatically by Flutter migrator
android.builtInKotlin=false
# This newDsl flag was added automatically by Flutter migrator
android.newDsl=false

View File

@@ -0,0 +1,6 @@
#Mon Mar 17 08:36:03 CET 2025
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
zipStoreBase=GRADLE_USER_HOME
zipStorePath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions/gradle-9.3.1-all.zip

View File

@@ -0,0 +1,28 @@
pluginManagement {
val flutterSdkPath = run {
val properties = java.util.Properties()
file("local.properties").inputStream().use { properties.load(it) }
val flutterSdkPath = properties.getProperty("flutter.sdk")
require(flutterSdkPath != null) { "flutter.sdk not set in local.properties" }
flutterSdkPath
}
includeBuild("$flutterSdkPath/packages/flutter_tools/gradle")
repositories {
google()
mavenCentral()
gradlePluginPortal()
}
}
plugins {
id("dev.flutter.flutter-plugin-loader") version "1.0.0"
id("com.android.application") version "8.11.1" apply false
id("org.jetbrains.kotlin.android") version "2.2.20" apply false
if (file("app/google-services.json").exists()) {
id("com.google.gms.google-services") version "4.3.8" apply false
}
}
include(":app")